-
Notifications
You must be signed in to change notification settings - Fork 10.5k
[AutoDiff] Add generated implicit declarations to SynthesizedFileUnit. #30863
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
f9ef75f
c834696
f7a9eed
de4deb5
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,63 @@ | ||
//===--- SynthesizedFileUnit.h - A synthesized file unit --------*- C++ -*-===// | ||
// | ||
// This source file is part of the Swift.org open source project | ||
// | ||
// Copyright (c) 2020 Apple Inc. and the Swift project authors | ||
// Licensed under Apache License v2.0 with Runtime Library Exception | ||
// | ||
// See https://swift.org/LICENSE.txt for license information | ||
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors | ||
// | ||
//===----------------------------------------------------------------------===// | ||
|
||
#ifndef SWIFT_AST_SYNTHESIZEDFILEUNIT_H | ||
#define SWIFT_AST_SYNTHESIZEDFILEUNIT_H | ||
|
||
#include "swift/AST/FileUnit.h" | ||
#include "swift/Basic/Debug.h" | ||
|
||
namespace swift { | ||
|
||
/// A container for synthesized module-level declarations. | ||
class SynthesizedFileUnit final : public FileUnit { | ||
/// Synthesized top level declarations. | ||
TinyPtrVector<ValueDecl *> TopLevelDecls; | ||
|
||
/// A unique identifier representing this file; used to mark private decls | ||
/// within the file to keep them from conflicting with other files in the | ||
/// same module. | ||
mutable Identifier PrivateDiscriminator; | ||
|
||
public: | ||
SynthesizedFileUnit(ModuleDecl &M); | ||
~SynthesizedFileUnit() = default; | ||
|
||
/// Add a synthesized top-level declaration. | ||
void addTopLevelDecl(ValueDecl *D) { TopLevelDecls.push_back(D); } | ||
|
||
virtual void lookupValue(DeclName name, NLKind lookupKind, | ||
SmallVectorImpl<ValueDecl *> &result) const override; | ||
|
||
void lookupObjCMethods( | ||
ObjCSelector selector, | ||
SmallVectorImpl<AbstractFunctionDecl *> &results) const override; | ||
|
||
Identifier getDiscriminatorForPrivateValue(const ValueDecl *D) const override; | ||
|
||
void getTopLevelDecls(SmallVectorImpl<Decl*> &results) const override; | ||
|
||
ArrayRef<ValueDecl *> getTopLevelDecls() const { | ||
return TopLevelDecls; | ||
}; | ||
|
||
static bool classof(const FileUnit *file) { | ||
return file->getKind() == FileUnitKind::Synthesized; | ||
} | ||
static bool classof(const DeclContext *DC) { | ||
return isa<FileUnit>(DC) && classof(cast<FileUnit>(DC)); | ||
} | ||
}; | ||
|
||
} // namespace swift | ||
|
||
#endif // SWIFT_AST_SYNTHESIZEDFILEUNIT_H |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -38,6 +38,7 @@ | |
#include "swift/AST/ProtocolConformance.h" | ||
#include "swift/AST/ReferencedNameTracker.h" | ||
#include "swift/AST/SourceFile.h" | ||
#include "swift/AST/SynthesizedFileUnit.h" | ||
#include "swift/AST/TypeCheckRequests.h" | ||
#include "swift/Basic/Compiler.h" | ||
#include "swift/Basic/SourceManager.h" | ||
|
@@ -218,6 +219,7 @@ class swift::SourceLookupCache { | |
|
||
SmallVector<ValueDecl *, 0> AllVisibleValues; | ||
}; | ||
|
||
SourceLookupCache &SourceFile::getCache() const { | ||
if (!Cache) { | ||
const_cast<SourceFile *>(this)->Cache = | ||
|
@@ -317,6 +319,10 @@ SourceLookupCache::SourceLookupCache(const ModuleDecl &M) { | |
FrontendStatsTracer tracer(M.getASTContext().Stats, | ||
"module-populate-cache"); | ||
for (const FileUnit *file : M.getFiles()) { | ||
if (auto *SFU = dyn_cast<SynthesizedFileUnit>(file)) { | ||
addToUnqualifiedLookupCache(SFU->getTopLevelDecls(), false); | ||
continue; | ||
} | ||
auto &SF = *cast<SourceFile>(file); | ||
addToUnqualifiedLookupCache(SF.getTopLevelDecls(), false); | ||
} | ||
|
@@ -1173,6 +1179,9 @@ lookupOperatorDeclForName(const FileUnit &File, SourceLoc Loc, | |
case FileUnitKind::Builtin: | ||
// The Builtin module declares no operators. | ||
return nullptr; | ||
case FileUnitKind::Synthesized: | ||
// Synthesized files currently declare no operators. | ||
return nullptr; | ||
case FileUnitKind::Source: | ||
break; | ||
case FileUnitKind::SerializedAST: | ||
|
@@ -1520,6 +1529,9 @@ StringRef ModuleDecl::getModuleFilename() const { | |
Result = LF->getFilename(); | ||
continue; | ||
} | ||
// Skip synthesized files. | ||
if (auto *SFU = dyn_cast<SynthesizedFileUnit>(F)) | ||
continue; | ||
return StringRef(); | ||
} | ||
return Result; | ||
|
@@ -2232,11 +2244,6 @@ SourceFile::getCachedVisibleDecls() const { | |
return getCache().AllVisibleValues; | ||
} | ||
|
||
void SourceFile::addVisibleDecl(ValueDecl *decl) { | ||
Decls->push_back(decl); | ||
getCache().AllVisibleValues.push_back(decl); | ||
} | ||
|
||
static void performAutoImport( | ||
SourceFile &SF, | ||
SourceFile::ImplicitModuleImportKind implicitModuleImportKind) { | ||
|
@@ -2662,6 +2669,70 @@ SourceFile::lookupOpaqueResultType(StringRef MangledName) { | |
return nullptr; | ||
} | ||
|
||
//===----------------------------------------------------------------------===// | ||
// SynthesizedFileUnit Implementation | ||
//===----------------------------------------------------------------------===// | ||
|
||
SynthesizedFileUnit::SynthesizedFileUnit(ModuleDecl &M) | ||
: FileUnit(FileUnitKind::Synthesized, M) { | ||
M.getASTContext().addDestructorCleanup(*this); | ||
} | ||
|
||
Identifier | ||
SynthesizedFileUnit::getDiscriminatorForPrivateValue(const ValueDecl *D) const { | ||
assert(D->getDeclContext()->getModuleScopeContext() == this); | ||
|
||
// Use cached primitive discriminator if it exists. | ||
if (!PrivateDiscriminator.empty()) | ||
return PrivateDiscriminator; | ||
|
||
assert(1 == count_if(getParentModule()->getFiles(), | ||
[](const FileUnit *FU) -> bool { | ||
return isa<SynthesizedFileUnit>(FU); | ||
}) && | ||
"Cannot promise uniqueness if multiple synthesized file units exist"); | ||
|
||
// Use a discriminator invariant across Swift version: a hash of the module | ||
// name and a special string. | ||
llvm::MD5 hash; | ||
hash.update(getParentModule()->getName().str()); | ||
// TODO: Use a more robust discriminator for synthesized files. Pick something | ||
// that cannot conflict with `SourceFile` discriminators. | ||
hash.update("SYNTHESIZED FILE"); | ||
llvm::MD5::MD5Result result; | ||
hash.final(result); | ||
|
||
// Use the hash as a hex string, prefixed with an underscore to make sure | ||
// it is a valid identifier. | ||
// FIXME: There are more compact ways to encode a 16-byte value. | ||
SmallString<33> buffer{"_"}; | ||
SmallString<32> hashString; | ||
llvm::MD5::stringifyResult(result, hashString); | ||
buffer += hashString; | ||
PrivateDiscriminator = getASTContext().getIdentifier(buffer.str().upper()); | ||
return PrivateDiscriminator; | ||
} | ||
|
||
void SynthesizedFileUnit::lookupValue( | ||
DeclName name, NLKind lookupKind, | ||
SmallVectorImpl<ValueDecl *> &result) const { | ||
for (auto *decl : TopLevelDecls) { | ||
if (decl->getFullName().matchesRef(name)) | ||
result.push_back(decl); | ||
} | ||
Comment on lines
+2719
to
+2722
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Note:
|
||
} | ||
|
||
void SynthesizedFileUnit::lookupObjCMethods( | ||
ObjCSelector selector, | ||
SmallVectorImpl<AbstractFunctionDecl *> &results) const { | ||
// Synthesized files only contain top-level declarations, no `@objc` methods. | ||
} | ||
|
||
void SynthesizedFileUnit::getTopLevelDecls( | ||
SmallVectorImpl<swift::Decl *> &results) const { | ||
results.append(TopLevelDecls.begin(), TopLevelDecls.end()); | ||
} | ||
|
||
//===----------------------------------------------------------------------===// | ||
// Miscellaneous | ||
//===----------------------------------------------------------------------===// | ||
|
@@ -2700,6 +2771,9 @@ void swift::simple_display(llvm::raw_ostream &out, const FileUnit *file) { | |
case FileUnitKind::Builtin: | ||
out << "(Builtin)"; | ||
return; | ||
case FileUnitKind::Synthesized: | ||
out << "(synthesized)"; | ||
return; | ||
case FileUnitKind::DWARFModule: | ||
case FileUnitKind::ClangModule: | ||
case FileUnitKind::SerializedAST: | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Note: consider robust discriminator ideas for synthesized files?
SynthesizedFileUnit
does not store any contents (e.g. name) useful for discrimination. Perhaps we could use file index (the nth synthesized file in the module), though I'm not sure that file order is robust.