Skip to content

Commit eb8e984

Browse files
authored
[Macros] Private discriminators for outermost-private MacroExpansionDecl (#64813)
Add a private discriminator to the mangling of an outermost-private `MacroExpansionDecl` so that declaration macros in different files won't have colliding macro expansion buffer names. rdar://107462515
1 parent 77bd312 commit eb8e984

24 files changed

+85
-50
lines changed

docs/ABI/Mangling.rst

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -394,13 +394,15 @@ Entities
394394
RELATED-DISCRIMINATOR ::= [a-j]
395395
RELATED-DISCRIMINATOR ::= [A-J]
396396

397-
macro-discriminator-list ::= macro-discriminator-list? 'fM' macro-expansion-operator INDEX
398-
399-
macro-expansion-operator ::= identifier 'a' // accessor attached macro
400-
macro-expansion-operator ::= identifier 'A' // member-attribute attached macro
401-
macro-expansion-operator ::= identifier 'f' // freestanding macro
402-
macro-expansion-operator ::= identifier 'm' // member attached macro
403-
macro-expansion-operator ::= identifier 'u' // uniquely-named entity
397+
macro-discriminator-list ::= macro-discriminator-list? file-discriminator? macro-expansion-operator INDEX
398+
399+
macro-expansion-operator ::= identifier 'fMa' // attached accessor macro
400+
macro-expansion-operator ::= identifier 'fMA' // attached member-attribute macro
401+
macro-expansion-operator ::= identifier 'fMf' // freestanding macro
402+
macro-expansion-operator ::= identifier 'fMm' // attached member macro
403+
macro-expansion-operator ::= identifier 'fMp' // attached peer macro
404+
macro-expansion-operator ::= identifier 'fMc' // attached conformance macro
405+
macro-expansion-operator ::= identifier 'fMu' // uniquely-named entity
404406

405407
file-discriminator ::= identifier 'Ll' // anonymous file-discriminated declaration
406408

include/swift/AST/Decl.h

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1156,6 +1156,10 @@ class alignas(1 << DeclAlignInBits) Decl : public ASTAllocated<Decl> {
11561156

11571157
bool isAvailableAsSPI() const;
11581158

1159+
/// Determine whether this Decl has either Private or FilePrivate access,
1160+
/// and its DeclContext does not.
1161+
bool isOutermostPrivateOrFilePrivateScope() const;
1162+
11591163
/// Retrieve the @available attribute that provides the OS version range that
11601164
/// this declaration is available in.
11611165
///
@@ -2570,10 +2574,6 @@ class ValueDecl : public Decl {
25702574
/// \sa hasOpenAccess
25712575
AccessLevel getFormalAccess() const;
25722576

2573-
/// Determine whether this Decl has either Private or FilePrivate access,
2574-
/// and its DeclContext does not.
2575-
bool isOutermostPrivateOrFilePrivateScope() const;
2576-
25772577
/// Returns the outermost DeclContext from which this declaration can be
25782578
/// accessed, or null if the declaration is public.
25792579
///

include/swift/AST/FileUnit.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -200,7 +200,7 @@ class FileUnit : public DeclContext, public ASTAllocated<FileUnit> {
200200
/// Since this value is used in name mangling, it should be a valid ASCII-only
201201
/// identifier.
202202
virtual Identifier
203-
getDiscriminatorForPrivateValue(const ValueDecl *D) const = 0;
203+
getDiscriminatorForPrivateDecl(const Decl *D) const = 0;
204204

205205
virtual bool shouldCollectDisplayDecls() const { return true; }
206206

@@ -389,7 +389,7 @@ class BuiltinUnit final : public FileUnit {
389389
SmallVectorImpl<AbstractFunctionDecl *> &results) const override;
390390

391391
Identifier
392-
getDiscriminatorForPrivateValue(const ValueDecl *D) const override {
392+
getDiscriminatorForPrivateDecl(const Decl *D) const override {
393393
llvm_unreachable("no private values in the Builtin module");
394394
}
395395

@@ -431,7 +431,7 @@ class LoadedFile : public FileUnit {
431431
return getModuleDefiningPath();
432432
}
433433

434-
virtual StringRef getFilenameForPrivateDecl(const ValueDecl *decl) const {
434+
virtual StringRef getFilenameForPrivateDecl(const Decl *decl) const {
435435
return StringRef();
436436
}
437437

include/swift/AST/SourceFile.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -490,7 +490,7 @@ class SourceFile final : public FileUnit {
490490
virtual void
491491
collectLinkLibraries(ModuleDecl::LinkLibraryCallback callback) const override;
492492

493-
Identifier getDiscriminatorForPrivateValue(const ValueDecl *D) const override;
493+
Identifier getDiscriminatorForPrivateDecl(const Decl *D) const override;
494494
Identifier getPrivateDiscriminator() const { return PrivateDiscriminator; }
495495
Optional<ExternalSourceLocs::RawLocs>
496496
getExternalRawLocsForDecl(const Decl *D) const override;

include/swift/AST/SynthesizedFileUnit.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ class SynthesizedFileUnit final : public FileUnit {
5050
ObjCSelector selector,
5151
SmallVectorImpl<AbstractFunctionDecl *> &results) const override;
5252

53-
Identifier getDiscriminatorForPrivateValue(const ValueDecl *D) const override;
53+
Identifier getDiscriminatorForPrivateDecl(const Decl *D) const override;
5454

5555
void getTopLevelDecls(SmallVectorImpl<Decl*> &results) const override;
5656

include/swift/ClangImporter/ClangModule.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -104,7 +104,7 @@ class ClangModuleUnit final : public LoadedFile {
104104
collectLinkLibraries(ModuleDecl::LinkLibraryCallback callback) const override;
105105

106106
Identifier
107-
getDiscriminatorForPrivateValue(const ValueDecl *D) const override {
107+
getDiscriminatorForPrivateDecl(const Decl *D) const override {
108108
llvm_unreachable("no private decls in Clang modules");
109109
}
110110

include/swift/Serialization/SerializedModuleLoader.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -363,7 +363,7 @@ class SerializedASTFile final : public LoadedFile {
363363
SmallVectorImpl<ValueDecl*> &results) const override;
364364

365365
virtual StringRef
366-
getFilenameForPrivateDecl(const ValueDecl *decl) const override;
366+
getFilenameForPrivateDecl(const Decl *decl) const override;
367367

368368
virtual TypeDecl *lookupLocalType(StringRef MangledName) const override;
369369

@@ -456,7 +456,7 @@ class SerializedASTFile final : public LoadedFile {
456456

457457
virtual void loadDependenciesForTestable(SourceLoc diagLoc) const override;
458458

459-
Identifier getDiscriminatorForPrivateValue(const ValueDecl *D) const override;
459+
Identifier getDiscriminatorForPrivateDecl(const Decl *D) const override;
460460

461461
virtual StringRef getFilename() const override;
462462

lib/AST/ASTMangler.cpp

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -959,7 +959,7 @@ static unsigned getUnnamedParamIndex(const ParamDecl *D) {
959959
llvm_unreachable("param not found");
960960
}
961961

962-
static StringRef getPrivateDiscriminatorIfNecessary(const ValueDecl *decl) {
962+
static StringRef getPrivateDiscriminatorIfNecessary(const Decl *decl) {
963963
if (!decl->isOutermostPrivateOrFilePrivateScope())
964964
return StringRef();
965965

@@ -969,7 +969,7 @@ static StringRef getPrivateDiscriminatorIfNecessary(const ValueDecl *decl) {
969969
auto fileUnit = cast<FileUnit>(topLevelSubcontext);
970970

971971
Identifier discriminator =
972-
fileUnit->getDiscriminatorForPrivateValue(decl);
972+
fileUnit->getDiscriminatorForPrivateDecl(decl);
973973
assert(!discriminator.empty());
974974
assert(!isNonAscii(discriminator.str()) &&
975975
"discriminator contains non-ASCII characters");
@@ -4005,6 +4005,11 @@ std::string ASTMangler::mangleMacroExpansion(
40054005
const MacroExpansionDecl *expansion) {
40064006
beginMangling();
40074007
appendMacroExpansionContext(expansion->getLoc(), expansion->getDeclContext());
4008+
auto privateDiscriminator = getPrivateDiscriminatorIfNecessary(expansion);
4009+
if (!privateDiscriminator.empty()) {
4010+
appendIdentifier(privateDiscriminator);
4011+
appendOperator("Ll");
4012+
}
40084013
appendMacroExpansionOperator(
40094014
expansion->getMacroName().getBaseName().userFacingName(),
40104015
MacroRole::Declaration,

lib/AST/Decl.cpp

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2697,13 +2697,15 @@ void AbstractStorageDecl::visitOpaqueAccessors(
26972697
});
26982698
}
26992699

2700-
static bool hasPrivateOrFilePrivateFormalAccess(const ValueDecl *D) {
2701-
return D->getFormalAccess() <= AccessLevel::FilePrivate;
2700+
static bool hasPrivateOrFilePrivateFormalAccess(const Decl *D) {
2701+
if (auto *VD = dyn_cast<ValueDecl>(D))
2702+
return VD->getFormalAccess() <= AccessLevel::FilePrivate;
2703+
return isa<MacroExpansionDecl>(D);
27022704
}
27032705

27042706
/// Returns true if one of the ancestor DeclContexts of this ValueDecl is either
27052707
/// marked private or fileprivate or is a local context.
2706-
static bool isInPrivateOrLocalContext(const ValueDecl *D) {
2708+
static bool isInPrivateOrLocalContext(const Decl *D) {
27072709
const DeclContext *DC = D->getDeclContext();
27082710
if (!DC->isTypeContext()) {
27092711
assert((DC->isModuleScopeContext() || DC->isLocalContext()) &&
@@ -2720,7 +2722,7 @@ static bool isInPrivateOrLocalContext(const ValueDecl *D) {
27202722
return isInPrivateOrLocalContext(nominal);
27212723
}
27222724

2723-
bool ValueDecl::isOutermostPrivateOrFilePrivateScope() const {
2725+
bool Decl::isOutermostPrivateOrFilePrivateScope() const {
27242726
return hasPrivateOrFilePrivateFormalAccess(this) &&
27252727
!isInPrivateOrLocalContext(this);
27262728
}

lib/AST/Module.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -990,7 +990,7 @@ void ModuleDecl::lookupMember(SmallVectorImpl<ValueDecl*> &results,
990990
return true;
991991
auto enclosingFile =
992992
cast<FileUnit>(VD->getDeclContext()->getModuleScopeContext());
993-
auto discriminator = enclosingFile->getDiscriminatorForPrivateValue(VD);
993+
auto discriminator = enclosingFile->getDiscriminatorForPrivateDecl(VD);
994994
return discriminator != privateDiscriminator;
995995
});
996996
results.erase(newEnd, results.end());
@@ -3818,7 +3818,7 @@ ASTScope &SourceFile::getScope() {
38183818
}
38193819

38203820
Identifier
3821-
SourceFile::getDiscriminatorForPrivateValue(const ValueDecl *D) const {
3821+
SourceFile::getDiscriminatorForPrivateDecl(const Decl *D) const {
38223822
assert(D->getDeclContext()->getModuleScopeContext() == this ||
38233823
D->getDeclContext()->getModuleScopeContext() == getSynthesizedFile());
38243824

@@ -3947,15 +3947,15 @@ SynthesizedFileUnit::SynthesizedFileUnit(FileUnit &FU)
39473947
}
39483948

39493949
Identifier
3950-
SynthesizedFileUnit::getDiscriminatorForPrivateValue(const ValueDecl *D) const {
3950+
SynthesizedFileUnit::getDiscriminatorForPrivateDecl(const Decl *D) const {
39513951
assert(D->getDeclContext()->getModuleScopeContext() == this);
39523952

39533953
// Use cached primitive discriminator if it exists.
39543954
if (!PrivateDiscriminator.empty())
39553955
return PrivateDiscriminator;
39563956

39573957
// Start with the discriminator that the file we belong to would use.
3958-
auto ownerDiscriminator = getFileUnit().getDiscriminatorForPrivateValue(D);
3958+
auto ownerDiscriminator = getFileUnit().getDiscriminatorForPrivateDecl(D);
39593959

39603960
// Hash that with a special string to produce a different value that preserves
39613961
// the entropy of the original.

0 commit comments

Comments
 (0)