Skip to content

Reimplement ModuleDecl::getSourceFileContainingLocation() using SourceManager #76551

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

Merged
merged 6 commits into from
Sep 18, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 0 additions & 17 deletions include/swift/AST/Module.h
Original file line number Diff line number Diff line change
Expand Up @@ -162,10 +162,6 @@ enum class ResilienceStrategy : unsigned {

class OverlayFile;

/// A mapping used to find the source file that contains a particular source
/// location.
class ModuleSourceFileLocationMap;

/// A unit that allows grouping of modules by a package name.
///
/// PackageUnit is treated as an enclosing scope of ModuleDecl. Unlike other
Expand Down Expand Up @@ -302,13 +298,6 @@ class ModuleDecl

SmallVector<FileUnit *, 2> Files;

/// Mapping used to find the source file associated with a given source
/// location.
ModuleSourceFileLocationMap *sourceFileLocationMap = nullptr;

/// The set of auxiliary source files build as part of this module.
SmallVector<SourceFile *, 2> AuxiliaryFiles;

llvm::SmallDenseMap<Identifier, SmallVector<OverlayFile *, 1>>
declaredCrossImports;

Expand Down Expand Up @@ -410,9 +399,6 @@ class ModuleDecl
/// SynthesizedFileUnit instead.
void addFile(FileUnit &newFile);

/// Add an auxiliary source file, introduced as part of the translation.
void addAuxiliaryFile(SourceFile &sourceFile);

/// Produces the source file that contains the given source location, or
/// \c nullptr if the source location isn't in this module.
SourceFile *getSourceFileContainingLocation(SourceLoc loc);
Expand Down Expand Up @@ -566,9 +552,6 @@ class ModuleDecl
/// present overlays as if they were part of their underlying module.
std::pair<ModuleDecl *, Identifier> getDeclaringModuleAndBystander();

/// Update the source-file location map to make it current.
void updateSourceFileLocationMap();

public:
/// If this is a traditional (non-cross-import) overlay, get its underlying
/// module if one exists.
Expand Down
10 changes: 3 additions & 7 deletions include/swift/AST/SourceFile.h
Original file line number Diff line number Diff line change
Expand Up @@ -156,9 +156,7 @@ class SourceFile final : public FileUnit {
std::optional<StableHasher> InterfaceHasher;

/// The ID for the memory buffer containing this file's source.
///
/// May be -1, to indicate no association with a buffer.
int BufferID;
unsigned BufferID;

/// The parsing options for the file.
ParsingOptions ParsingOpts;
Expand Down Expand Up @@ -370,7 +368,7 @@ class SourceFile final : public FileUnit {
/// \c #sourceLocation(file:) declarations.
llvm::StringMap<SourceFilePathInfo> getInfoForUsedFilePaths() const;

SourceFile(ModuleDecl &M, SourceFileKind K, std::optional<unsigned> bufferID,
SourceFile(ModuleDecl &M, SourceFileKind K, unsigned bufferID,
ParsingOptions parsingOpts = {}, bool isPrimary = false);

~SourceFile();
Expand Down Expand Up @@ -590,9 +588,7 @@ class SourceFile final : public FileUnit {

/// The buffer ID for the file that was imported, or None if there
/// is no associated buffer.
std::optional<unsigned> getBufferID() const {
if (BufferID == -1)
return std::nullopt;
unsigned getBufferID() const {
return BufferID;
}

Expand Down
33 changes: 33 additions & 0 deletions include/swift/Basic/SourceManager.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,15 +18,34 @@
#include "clang/Basic/FileManager.h"
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/DenseSet.h"
#include "llvm/ADT/TinyPtrVector.h"
#include "llvm/Support/SourceMgr.h"
#include <map>
#include <optional>
#include <vector>

namespace swift {
class SourceFile;
}

namespace llvm {
template <> struct PointerLikeTypeTraits<swift::SourceFile *> {
public:
static inline swift::SourceFile *getFromVoidPointer(void *P) {
return (swift::SourceFile *)P;
}
static inline void *getAsVoidPointer(swift::SourceFile *S) {
return (void *)S;
}
enum { NumLowBitsAvailable = /*swift::DeclContextAlignInBits=*/ 3 };
};
}

namespace swift {

class CustomAttr;
class DeclContext;
class SourceFile;

/// Augments a buffer that was created specifically to hold generated source
/// code with the reasons for it being generated.
Expand Down Expand Up @@ -123,6 +142,13 @@ class SourceManager {
/// is an unfortunate hack needed to allow for correct re-lexing.
llvm::DenseSet<SourceLoc> RegexLiteralStartLocs;

/// Mapping from each buffer ID to the source files that describe it
/// semantically.
llvm::DenseMap<
unsigned,
llvm::TinyPtrVector<SourceFile *>
> bufferIDToSourceFiles;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would you remind me of scenarios where multiple SourceFile can reference the same buffer?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The only place I've seen this happen thus far is in the Clang importer, where it's effectively uniquing the text of C __attribute__((swift_attr("<this is a Swift attribute>"))) to not create lots of buffers, but it still needs to provide a different SourceFile * for each imported module.

We might consider doing similar uniquing for macro expansion buffers, because there could be a lot of identical buffers.


std::map<const char *, VirtualFile> VirtualFiles;
mutable std::pair<const char *, const VirtualFile*> CachedVFile = {nullptr, nullptr};

Expand Down Expand Up @@ -323,6 +349,13 @@ class SourceManager {
/// Adds a memory buffer to the SourceManager, taking ownership of it.
unsigned addNewSourceBuffer(std::unique_ptr<llvm::MemoryBuffer> Buffer);

/// Record the source file as having the given buffer ID.
void recordSourceFile(unsigned bufferID, SourceFile *sourceFile);

/// Retrieve the source files for the given buffer ID.
llvm::TinyPtrVector<SourceFile *>
getSourceFilesForBufferID(unsigned bufferID) const;

/// Add a \c #sourceLocation-defined virtual file region of \p Length.
void createVirtualFile(SourceLoc Loc, StringRef Name, int LineOffset,
unsigned Length);
Expand Down
2 changes: 1 addition & 1 deletion include/swift/Frontend/Frontend.h
Original file line number Diff line number Diff line change
Expand Up @@ -789,7 +789,7 @@ class CompilerInstance {
/// Creates a new source file for the main module.
SourceFile *createSourceFileForMainModule(ModuleDecl *mod,
SourceFileKind FileKind,
std::optional<unsigned> BufferID,
unsigned BufferID,
bool isMainBuffer = false) const;

/// Creates all the files to be added to the main module, appending them to
Expand Down
4 changes: 2 additions & 2 deletions include/swift/IDE/IDERequests.h
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ struct CursorInfoOwner {
return !(lhs == rhs);
}
bool isValid() const {
return File && File->getBufferID() && Loc.isValid();
return File && Loc.isValid();
}
};

Expand Down Expand Up @@ -110,7 +110,7 @@ struct RangeInfoOwner {
}

bool isValid() const {
return File && File->getBufferID() && StartLoc.isValid() && EndLoc.isValid();
return File && StartLoc.isValid() && EndLoc.isValid();
}
};

Expand Down
2 changes: 1 addition & 1 deletion include/swift/Migrator/ASTMigratorPass.h
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ class ASTMigratorPass {
ASTMigratorPass(EditorAdapter &Editor, SourceFile *SF,
const MigratorOptions &Opts)
: Editor(Editor), SF(SF), Opts(Opts), Filename(SF->getFilename()),
BufferID(SF->getBufferID().value()),
BufferID(SF->getBufferID()),
SM(SF->getASTContext().SourceMgr), Diags(SF->getASTContext().Diags) {}
};

Expand Down
3 changes: 1 addition & 2 deletions lib/AST/ASTContext.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6622,9 +6622,8 @@ void VarDecl::setOriginalWrappedProperty(VarDecl *originalProperty) {
static bool isSourceLocInOrignalBuffer(const Decl *D, SourceLoc Loc) {
assert(Loc.isValid());
auto bufferID = D->getDeclContext()->getParentSourceFile()->getBufferID();
assert(bufferID.has_value() && "Source buffer ID must be set");
auto &SM = D->getASTContext().SourceMgr;
return SM.getRangeForBuffer(*bufferID).contains(Loc);
return SM.getRangeForBuffer(bufferID).contains(Loc);
}
#endif

Expand Down
2 changes: 1 addition & 1 deletion lib/AST/ASTScopeCreation.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -272,7 +272,7 @@ ASTSourceFileScope::ASTSourceFileScope(SourceFile *SF,

if (SF->Kind == SourceFileKind::DefaultArgument) {
auto genInfo = *SF->getASTContext().SourceMgr.getGeneratedSourceInfo(
*SF->getBufferID());
SF->getBufferID());
parentLoc = ASTNode::getFromOpaqueValue(genInfo.astNode).getStartLoc();
if (auto parentScope =
findStartingScopeForLookup(enclosingSF, parentLoc)) {
Expand Down
7 changes: 1 addition & 6 deletions lib/AST/ASTScopePrinting.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -43,13 +43,8 @@ void ASTScopeImpl::dump() const { print(llvm::errs(), 0, false); }
void ASTScopeImpl::dumpOneScopeMapLocation(
std::pair<unsigned, unsigned> lineColumn) {
auto bufferID = getSourceFile()->getBufferID();
if (!bufferID) {
llvm::errs() << "***No buffer, dumping all scopes***";
print(llvm::errs());
return;
}
SourceLoc loc = getSourceManager().getLocForLineCol(
*bufferID, lineColumn.first, lineColumn.second);
bufferID, lineColumn.first, lineColumn.second);
if (loc.isInvalid())
return;

Expand Down
14 changes: 3 additions & 11 deletions lib/AST/ASTScopeSourceRange.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -203,17 +203,9 @@ SourceRange GenericParamScope::getSourceRangeOfThisASTNode(

SourceRange ASTSourceFileScope::getSourceRangeOfThisASTNode(
const bool omitAssertions) const {
if (auto bufferID = SF->getBufferID()) {
auto charRange = getSourceManager().getRangeForBuffer(*bufferID);
return SourceRange(charRange.getStart(), charRange.getEnd());
}

if (SF->getTopLevelItems().empty())
return SourceRange();

// Use the source ranges of the declarations in the file.
return SourceRange(SF->getTopLevelItems().front().getStartLoc(),
SF->getTopLevelItems().back().getEndLoc());
auto bufferID = SF->getBufferID();
auto charRange = getSourceManager().getRangeForBuffer(bufferID);
return SourceRange(charRange.getStart(), charRange.getEnd());
}

SourceRange GenericTypeOrExtensionScope::getSourceRangeOfThisASTNode(
Expand Down
4 changes: 1 addition & 3 deletions lib/AST/DiagnosticEngine.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1759,9 +1759,7 @@ BufferIndirectlyCausingDiagnosticRAII::BufferIndirectlyCausingDiagnosticRAII(
const SourceFile &SF)
: Diags(SF.getASTContext().Diags) {
auto id = SF.getBufferID();
if (!id)
return;
auto loc = SF.getASTContext().SourceMgr.getLocForBufferStart(*id);
auto loc = SF.getASTContext().SourceMgr.getLocForBufferStart(id);
if (loc.isValid())
Diags.setBufferIndirectlyCausingDiagnosticToInput(loc);
}
Expand Down
Loading