Skip to content

Commit e130826

Browse files
committed
[NFC] Attach SynthesizedFile to any FileUnit
Gives us a place to stuff synthesized declarations for, among other things, imported Clang decls.
1 parent 7549278 commit e130826

File tree

7 files changed

+48
-50
lines changed

7 files changed

+48
-50
lines changed

include/swift/AST/FileUnit.h

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,11 @@
1717
#include "swift/AST/RawComment.h"
1818
#include "swift/Basic/BasicSourceInfo.h"
1919

20+
#include "llvm/ADT/PointerIntPair.h"
21+
2022
namespace swift {
23+
class SynthesizedFileUnit;
24+
2125
/// A container for module-scope declarations that itself provides a scope; the
2226
/// smallest unit of code organization.
2327
///
@@ -33,19 +37,25 @@ class FileUnit : public DeclContext, public ASTAllocated<FileUnit> {
3337
friend class DirectOperatorLookupRequest;
3438
friend class DirectPrecedenceGroupLookupRequest;
3539

36-
// FIXME: Stick this in a PointerIntPair.
37-
const FileUnitKind Kind;
40+
// The pointer is FileUnit insted of SynthesizedFileUnit to break circularity.
41+
llvm::PointerIntPair<FileUnit *, 3, FileUnitKind> SynthesizedFileAndKind;
3842

3943
protected:
4044
FileUnit(FileUnitKind kind, ModuleDecl &M)
41-
: DeclContext(DeclContextKind::FileUnit, &M), Kind(kind) {
45+
: DeclContext(DeclContextKind::FileUnit, &M),
46+
SynthesizedFileAndKind(nullptr, kind) {
4247
}
4348

4449
public:
4550
FileUnitKind getKind() const {
46-
return Kind;
51+
return SynthesizedFileAndKind.getInt();
4752
}
4853

54+
/// Returns the synthesized file for this source file, if it exists.
55+
SynthesizedFileUnit *getSynthesizedFile() const;
56+
57+
SynthesizedFileUnit &getOrCreateSynthesizedFile();
58+
4959
/// Look up a (possibly overloaded) value set at top-level scope
5060
/// (but with the specified access path, which may come from an import decl)
5161
/// within this file.

include/swift/AST/SourceFile.h

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -89,9 +89,6 @@ class SourceFile final : public FileUnit {
8989
/// same module.
9090
mutable Identifier PrivateDiscriminator;
9191

92-
/// A synthesized file corresponding to this file, created on-demand.
93-
SynthesizedFileUnit *SynthesizedFile = nullptr;
94-
9592
/// The root TypeRefinementContext for this SourceFile.
9693
///
9794
/// This is set during type checking.
@@ -409,11 +406,6 @@ class SourceFile final : public FileUnit {
409406
Optional<ExternalSourceLocs::RawLocs>
410407
getExternalRawLocsForDecl(const Decl *D) const override;
411408

412-
/// Returns the synthesized file for this source file, if it exists.
413-
SynthesizedFileUnit *getSynthesizedFile() const { return SynthesizedFile; };
414-
415-
SynthesizedFileUnit &getOrCreateSynthesizedFile();
416-
417409
virtual bool walk(ASTWalker &walker) override;
418410

419411
/// The buffer ID for the file that was imported, or None if there

include/swift/AST/SynthesizedFileUnit.h

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -18,14 +18,12 @@
1818

1919
namespace swift {
2020

21-
class SourceFile;
22-
2321
/// A container for synthesized declarations, attached to a `SourceFile`.
2422
///
2523
/// Currently, only module-level synthesized declarations are supported.
2624
class SynthesizedFileUnit final : public FileUnit {
2725
/// The parent source file.
28-
SourceFile &SF;
26+
FileUnit &FU;
2927

3028
/// Synthesized top level declarations.
3129
TinyPtrVector<Decl *> TopLevelDecls;
@@ -36,11 +34,11 @@ class SynthesizedFileUnit final : public FileUnit {
3634
mutable Identifier PrivateDiscriminator;
3735

3836
public:
39-
SynthesizedFileUnit(SourceFile &SF);
37+
SynthesizedFileUnit(FileUnit &FU);
4038
~SynthesizedFileUnit() = default;
4139

4240
/// Returns the parent source file.
43-
SourceFile &getSourceFile() const { return SF; }
41+
FileUnit &getFileUnit() const { return FU; }
4442

4543
/// Add a synthesized top-level declaration.
4644
void addTopLevelDecl(Decl *D) { TopLevelDecls.push_back(D); }

lib/AST/Module.cpp

Lines changed: 24 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -2857,7 +2857,8 @@ ASTScope &SourceFile::getScope() {
28572857

28582858
Identifier
28592859
SourceFile::getDiscriminatorForPrivateValue(const ValueDecl *D) const {
2860-
assert(D->getDeclContext()->getModuleScopeContext() == this);
2860+
assert(D->getDeclContext()->getModuleScopeContext() == this ||
2861+
D->getDeclContext()->getModuleScopeContext() == getSynthesizedFile());
28612862

28622863
if (!PrivateDiscriminator.empty())
28632864
return PrivateDiscriminator;
@@ -2896,11 +2897,19 @@ SourceFile::getDiscriminatorForPrivateValue(const ValueDecl *D) const {
28962897
return PrivateDiscriminator;
28972898
}
28982899

2899-
SynthesizedFileUnit &SourceFile::getOrCreateSynthesizedFile() {
2900-
if (SynthesizedFile)
2901-
return *SynthesizedFile;
2902-
SynthesizedFile = new (getASTContext()) SynthesizedFileUnit(*this);
2903-
getParentModule()->addFile(*SynthesizedFile);
2900+
SynthesizedFileUnit *FileUnit::getSynthesizedFile() const {
2901+
return cast_or_null<SynthesizedFileUnit>(SynthesizedFileAndKind.getPointer());
2902+
}
2903+
2904+
SynthesizedFileUnit &FileUnit::getOrCreateSynthesizedFile() {
2905+
auto SynthesizedFile = getSynthesizedFile();
2906+
if (!SynthesizedFile) {
2907+
if (auto thisSynth = dyn_cast<SynthesizedFileUnit>(this))
2908+
return *thisSynth;
2909+
SynthesizedFile = new (getASTContext()) SynthesizedFileUnit(*this);
2910+
SynthesizedFileAndKind.setPointer(SynthesizedFile);
2911+
getParentModule()->addFile(*SynthesizedFile);
2912+
}
29042913
return *SynthesizedFile;
29052914
}
29062915

@@ -2950,9 +2959,9 @@ SourceFile::lookupOpaqueResultType(StringRef MangledName) {
29502959
// SynthesizedFileUnit Implementation
29512960
//===----------------------------------------------------------------------===//
29522961

2953-
SynthesizedFileUnit::SynthesizedFileUnit(SourceFile &SF)
2954-
: FileUnit(FileUnitKind::Synthesized, *SF.getParentModule()), SF(SF) {
2955-
SF.getASTContext().addDestructorCleanup(*this);
2962+
SynthesizedFileUnit::SynthesizedFileUnit(FileUnit &FU)
2963+
: FileUnit(FileUnitKind::Synthesized, *FU.getParentModule()), FU(FU) {
2964+
FU.getASTContext().addDestructorCleanup(*this);
29562965
}
29572966

29582967
Identifier
@@ -2963,23 +2972,15 @@ SynthesizedFileUnit::getDiscriminatorForPrivateValue(const ValueDecl *D) const {
29632972
if (!PrivateDiscriminator.empty())
29642973
return PrivateDiscriminator;
29652974

2966-
StringRef sourceFileName = getSourceFile().getFilename();
2967-
if (sourceFileName.empty()) {
2968-
assert(1 == count_if(getParentModule()->getFiles(),
2969-
[](const FileUnit *FU) -> bool {
2970-
return isa<SourceFile>(FU) &&
2971-
cast<SourceFile>(FU)->getFilename().empty();
2972-
}) &&
2973-
"Cannot promise uniqueness if multiple source files are nameless");
2974-
}
2975+
// Start with the discriminator that the file we belong to would use.
2976+
auto ownerDiscriminator = getFileUnit().getDiscriminatorForPrivateValue(D);
29752977

2976-
// Use a discriminator invariant across Swift version: a hash of the module
2977-
// name, the parent source file name, and a special string.
2978-
llvm::MD5 hash;
2979-
hash.update(getParentModule()->getName().str());
2980-
hash.update(llvm::sys::path::filename(sourceFileName));
2978+
// Hash that with a special string to produce a different value that preserves
2979+
// the entropy of the original.
29812980
// TODO: Use a more robust discriminator for synthesized files. Pick something
29822981
// that cannot conflict with `SourceFile` discriminators.
2982+
llvm::MD5 hash;
2983+
hash.update(ownerDiscriminator.str());
29832984
hash.update("SYNTHESIZED FILE");
29842985
llvm::MD5::MD5Result result;
29852986
hash.final(result);

lib/IRGen/IRGenRequests.cpp

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -68,10 +68,9 @@ TinyPtrVector<FileUnit *> IRGenDescriptor::getFilesToEmit() const {
6868
TinyPtrVector<FileUnit *> files;
6969
files.push_back(primary);
7070

71-
if (auto *SF = dyn_cast<SourceFile>(primary)) {
72-
if (auto *synthesizedFile = SF->getSynthesizedFile())
73-
files.push_back(synthesizedFile);
74-
}
71+
if (auto *synthesizedFile = primary->getSynthesizedFile())
72+
files.push_back(synthesizedFile);
73+
7574
return files;
7675
}
7776

lib/Sema/TypeCheckConcurrency.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4018,8 +4018,8 @@ NormalProtocolConformance *GetImplicitSendableRequest::evaluate(
40184018
nominal->addExtension(extension);
40194019

40204020
// Make it accessible to getTopLevelDecls()
4021-
if (auto sf = dyn_cast<SourceFile>(nominal->getModuleScopeContext()))
4022-
sf->getOrCreateSynthesizedFile().addTopLevelDecl(extension);
4021+
if (auto file = dyn_cast<FileUnit>(nominal->getModuleScopeContext()))
4022+
file->getOrCreateSynthesizedFile().addTopLevelDecl(extension);
40234023

40244024
conformanceDC = extension;
40254025
}

lib/TBDGen/TBDGen.cpp

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1203,10 +1203,8 @@ void TBDGenVisitor::visit(const TBDGenDescriptor &desc) {
12031203
visitFile(singleFile);
12041204

12051205
// Visit synthesized file, if it exists.
1206-
if (auto *SF = dyn_cast<SourceFile>(singleFile)) {
1207-
if (auto *synthesizedFile = SF->getSynthesizedFile())
1208-
visitFile(synthesizedFile);
1209-
}
1206+
if (auto *synthesizedFile = singleFile->getSynthesizedFile())
1207+
visitFile(synthesizedFile);
12101208
return;
12111209
}
12121210

0 commit comments

Comments
 (0)