mirror of
https://github.com/apple/swift.git
synced 2025-12-21 12:14:44 +01:00
SerializeLoc: serialize basic decl source location information to .swiftsourceinfo file
After setting up the .swiftsourceinfo file, this patch starts to actually serialize and de-serialize source locations for declaration. The binary format of .swiftsourceinfo currently contains these three records: BasicDeclLocs: a hash table mapping from a USR ID to a list of basic source locations. The USR id could be retrieved from the following DeclUSRs record using an actual decl USR. The basic source locations include a file ID and the results from Decl::getLoc(), ValueDecl::getNameLoc(), Decl::getStartLoc() and Decl::getEndLoc(). The file ID could be used to retrieve the actual file name from the following SourceFilePaths record. Each location is encoded as a line:column pair. DeclUSRS: a hash table mapping from USR to a USR ID used by location records. SourceFilePaths: a hash table mapping from a file ID to actual file name. BasicDeclLocs should be sufficient for most diagnostic cases. If additional source locations are needed, we could always add new source location records without breaking the backward compatibility. When de-serializing the source location from a module-imported decl, we calculate its USR, retrieve the USR ID from the DeclUSRS record, and use the USR ID to look up the basic location list in the BasicDeclLocs record. For more details about .swiftsourceinfo file: https://forums.swift.org/t/proposal-emitting-source-information-file-during-compilation
This commit is contained in:
@@ -468,38 +468,35 @@ Optional<unsigned> CompilerInstance::getRecordedBufferID(const InputFile &input,
|
||||
return existingBufferID;
|
||||
}
|
||||
}
|
||||
std::pair<std::unique_ptr<llvm::MemoryBuffer>,
|
||||
std::unique_ptr<llvm::MemoryBuffer>>
|
||||
buffers = getInputBufferAndModuleDocBufferIfPresent(input);
|
||||
auto buffers = getInputBuffersIfPresent(input);
|
||||
|
||||
if (!buffers.first) {
|
||||
if (!buffers.ModuleBuffer) {
|
||||
failed = true;
|
||||
return None;
|
||||
}
|
||||
|
||||
// FIXME: The fact that this test happens twice, for some cases,
|
||||
// suggests that setupInputs could use another round of refactoring.
|
||||
if (serialization::isSerializedAST(buffers.first->getBuffer())) {
|
||||
if (serialization::isSerializedAST(buffers.ModuleBuffer->getBuffer())) {
|
||||
PartialModules.push_back(
|
||||
{std::move(buffers.first), std::move(buffers.second)});
|
||||
{std::move(buffers.ModuleBuffer), std::move(buffers.ModuleDocBuffer),
|
||||
std::move(buffers.ModuleSourceInfoBuffer)});
|
||||
return None;
|
||||
}
|
||||
assert(buffers.second.get() == nullptr);
|
||||
assert(buffers.ModuleDocBuffer.get() == nullptr);
|
||||
assert(buffers.ModuleSourceInfoBuffer.get() == nullptr);
|
||||
// Transfer ownership of the MemoryBuffer to the SourceMgr.
|
||||
unsigned bufferID = SourceMgr.addNewSourceBuffer(std::move(buffers.first));
|
||||
unsigned bufferID = SourceMgr.addNewSourceBuffer(std::move(buffers.ModuleBuffer));
|
||||
|
||||
InputSourceCodeBufferIDs.push_back(bufferID);
|
||||
return bufferID;
|
||||
}
|
||||
|
||||
std::pair<std::unique_ptr<llvm::MemoryBuffer>,
|
||||
std::unique_ptr<llvm::MemoryBuffer>>
|
||||
CompilerInstance::getInputBufferAndModuleDocBufferIfPresent(
|
||||
CompilerInstance::ModuleBuffers CompilerInstance::getInputBuffersIfPresent(
|
||||
const InputFile &input) {
|
||||
if (auto b = input.buffer()) {
|
||||
return std::make_pair(llvm::MemoryBuffer::getMemBufferCopy(
|
||||
b->getBuffer(), b->getBufferIdentifier()),
|
||||
nullptr);
|
||||
return {llvm::MemoryBuffer::getMemBufferCopy(b->getBuffer(), b->getBufferIdentifier()),
|
||||
nullptr, nullptr};
|
||||
}
|
||||
// FIXME: Working with filenames is fragile, maybe use the real path
|
||||
// or have some kind of FileManager.
|
||||
@@ -509,17 +506,37 @@ CompilerInstance::getInputBufferAndModuleDocBufferIfPresent(
|
||||
if (!inputFileOrErr) {
|
||||
Diagnostics.diagnose(SourceLoc(), diag::error_open_input_file, input.file(),
|
||||
inputFileOrErr.getError().message());
|
||||
return std::make_pair(nullptr, nullptr);
|
||||
return {nullptr, nullptr, nullptr};
|
||||
}
|
||||
if (!serialization::isSerializedAST((*inputFileOrErr)->getBuffer()))
|
||||
return std::make_pair(std::move(*inputFileOrErr), nullptr);
|
||||
return {std::move(*inputFileOrErr), nullptr, nullptr};
|
||||
|
||||
if (Optional<std::unique_ptr<llvm::MemoryBuffer>> moduleDocBuffer =
|
||||
openModuleDoc(input)) {
|
||||
return std::make_pair(std::move(*inputFileOrErr),
|
||||
std::move(*moduleDocBuffer));
|
||||
}
|
||||
return std::make_pair(nullptr, nullptr);
|
||||
Optional<std::unique_ptr<llvm::MemoryBuffer>> moduleDocBuffer = openModuleDoc(input);
|
||||
Optional<std::unique_ptr<llvm::MemoryBuffer>> moduleSourceInfoBuffer = openModuleSourceInfo(input);
|
||||
|
||||
return {
|
||||
std::move(*inputFileOrErr),
|
||||
moduleDocBuffer.hasValue() ? std::move(*moduleDocBuffer): nullptr,
|
||||
moduleSourceInfoBuffer.hasValue() ? std::move(*moduleSourceInfoBuffer): nullptr
|
||||
};
|
||||
}
|
||||
|
||||
Optional<std::unique_ptr<llvm::MemoryBuffer>>
|
||||
CompilerInstance::openModuleSourceInfo(const InputFile &input) {
|
||||
llvm::SmallString<128> moduleSourceInfoFilePath(input.file());
|
||||
llvm::sys::path::replace_extension(moduleSourceInfoFilePath,
|
||||
file_types::getExtension(file_types::TY_SwiftSourceInfoFile));
|
||||
std::string NonPrivatePath = moduleSourceInfoFilePath.str().str();
|
||||
StringRef fileName = llvm::sys::path::filename(NonPrivatePath);
|
||||
llvm::sys::path::remove_filename(moduleSourceInfoFilePath);
|
||||
llvm::sys::path::append(moduleSourceInfoFilePath, "Private");
|
||||
llvm::sys::path::append(moduleSourceInfoFilePath, fileName);
|
||||
if (auto sourceInfoFileOrErr = swift::vfs::getFileOrSTDIN(getFileSystem(),
|
||||
moduleSourceInfoFilePath))
|
||||
return std::move(*sourceInfoFileOrErr);
|
||||
if (auto sourceInfoFileOrErr = swift::vfs::getFileOrSTDIN(getFileSystem(), NonPrivatePath))
|
||||
return std::move(*sourceInfoFileOrErr);
|
||||
return None;
|
||||
}
|
||||
|
||||
Optional<std::unique_ptr<llvm::MemoryBuffer>>
|
||||
@@ -896,7 +913,8 @@ bool CompilerInstance::parsePartialModulesAndLibraryFiles(
|
||||
for (auto &PM : PartialModules) {
|
||||
assert(PM.ModuleBuffer);
|
||||
if (!SML->loadAST(*MainModule, SourceLoc(), std::move(PM.ModuleBuffer),
|
||||
std::move(PM.ModuleDocBuffer), /*isFramework*/false,
|
||||
std::move(PM.ModuleDocBuffer),
|
||||
std::move(PM.ModuleSourceInfoBuffer), /*isFramework*/false,
|
||||
/*treatAsPartialModule*/true))
|
||||
hadLoadError = true;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user