SerializeLoc: address more comments from Jordan. NFC

This commit is contained in:
Xi Ge
2019-10-09 10:40:29 -07:00
parent adaf790f4c
commit 014f863546
10 changed files with 139 additions and 119 deletions

View File

@@ -89,8 +89,8 @@ protected:
StringRef ModuleDocPath,
std::unique_ptr<llvm::MemoryBuffer> *ModuleDocBuffer);
std::error_code
openModuleSourceInfoFile(AccessPathElem ModuleID,
void
openModuleSourceInfoFileIfPresent(AccessPathElem ModuleID,
StringRef ModulePath,
StringRef ModuleSourceInfoFileName,
std::unique_ptr<llvm::MemoryBuffer> *ModuleSourceInfoBuffer);

View File

@@ -2793,7 +2793,7 @@ static void chooseModuleAuxiliaryOutputFilePath(Compilation &C,
StringRef workingDirectory,
CommandOutput *Output,
file_types::ID fileID,
bool isProject = false,
bool shouldUseProjectFolder = false,
Optional<options::ID> optId = llvm::None) {
if (hasExistingAdditionalOutput(*Output, fileID))
return;
@@ -2819,7 +2819,7 @@ static void chooseModuleAuxiliaryOutputFilePath(Compilation &C,
bool isTempFile = C.isTemporaryFile(ModulePath);
auto ModuleName = llvm::sys::path::filename(ModulePath);
llvm::SmallString<128> Path(llvm::sys::path::parent_path(ModulePath));
if (isProject) {
if (shouldUseProjectFolder) {
llvm::sys::path::append(Path, "Project");
// If the build system has created a Project dir for us to include the file, use it.
if (!llvm::sys::fs::exists(Path)) {
@@ -2840,7 +2840,8 @@ void Driver::chooseSwiftSourceInfoOutputPath(Compilation &C,
CommandOutput *Output) const {
chooseModuleAuxiliaryOutputFilePath(C, OutputMap, workingDirectory, Output,
file_types::TY_SwiftSourceInfoFile,
/*isProject*/true, options::OPT_emit_module_source_info_path);
/*shouldUseProjectFolder*/true,
options::OPT_emit_module_source_info_path);
}
void Driver::chooseSwiftModuleDocOutputPath(Compilation &C,

View File

@@ -520,18 +520,19 @@ Optional<CompilerInstance::ModuleBuffers> CompilerInstance::getInputBuffersIfPre
Optional<std::unique_ptr<llvm::MemoryBuffer>>
CompilerInstance::openModuleSourceInfo(const InputFile &input) {
llvm::SmallString<128> moduleSourceInfoFilePath(input.file());
llvm::sys::path::replace_extension(moduleSourceInfoFilePath,
llvm::SmallString<128> pathWithoutProjectDir(input.file());
llvm::sys::path::replace_extension(pathWithoutProjectDir,
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, "Project");
llvm::sys::path::append(moduleSourceInfoFilePath, fileName);
llvm::SmallString<128> pathWithProjectDir = pathWithoutProjectDir.str();
StringRef fileName = llvm::sys::path::filename(pathWithoutProjectDir);
llvm::sys::path::remove_filename(pathWithProjectDir);
llvm::sys::path::append(pathWithProjectDir, "Project");
llvm::sys::path::append(pathWithProjectDir, fileName);
if (auto sourceInfoFileOrErr = swift::vfs::getFileOrSTDIN(getFileSystem(),
moduleSourceInfoFilePath))
pathWithProjectDir))
return std::move(*sourceInfoFileOrErr);
if (auto sourceInfoFileOrErr = swift::vfs::getFileOrSTDIN(getFileSystem(), NonPrivatePath))
if (auto sourceInfoFileOrErr = swift::vfs::getFileOrSTDIN(getFileSystem(),
pathWithoutProjectDir))
return std::move(*sourceInfoFileOrErr);
return None;
}

View File

@@ -1037,7 +1037,8 @@ std::error_code ModuleInterfaceLoader::findModuleFilesInDirectory(
*ModuleBuffer = std::move(*ModuleBufferOrErr);
}
// Open .swiftsourceinfo file if it's present.
SerializedModuleLoaderBase::openModuleSourceInfoFile(ModuleID, ModPath,
SerializedModuleLoaderBase::openModuleSourceInfoFileIfPresent(ModuleID,
ModPath,
ModuleSourceInfoFilename,
ModuleSourceInfoBuffer);
// Delegate back to the serialized module loader to load the module doc.

View File

@@ -1224,7 +1224,7 @@ bool ModuleFile::readModuleDocIfPresent() {
}
class ModuleFile::DeclUSRTableInfo {
public:
public:
using internal_key_type = StringRef;
using external_key_type = StringRef;
using data_type = uint32_t;
@@ -1238,7 +1238,9 @@ class ModuleFile::DeclUSRTableInfo {
return llvm::djbHash(key, SWIFTSOURCEINFO_HASH_SEED);
}
static bool EqualKey(internal_key_type lhs, internal_key_type rhs) { return lhs == rhs; }
static bool EqualKey(internal_key_type lhs, internal_key_type rhs) {
return lhs == rhs;
}
static std::pair<unsigned, unsigned> ReadKeyDataLength(const uint8_t *&data) {
unsigned keyLength = endian::readNext<uint32_t, little, unaligned>(data);
@@ -1252,7 +1254,7 @@ class ModuleFile::DeclUSRTableInfo {
data_type ReadData(internal_key_type key, const uint8_t *data, unsigned length) {
assert(length == 4);
return *reinterpret_cast<const uint32_t*>(data);
return endian::readNext<uint32_t, little, unaligned>(data);
}
};
@@ -1263,8 +1265,8 @@ ModuleFile::readDeclUSRsTable(ArrayRef<uint64_t> fields, StringRef blobData) {
uint32_t tableOffset = static_cast<uint32_t>(fields.front());
auto base = reinterpret_cast<const uint8_t *>(blobData.data());
return std::unique_ptr<SerializedDeclUSRTable>(
SerializedDeclUSRTable::Create(base + tableOffset, base + sizeof(uint32_t), base,
DeclUSRTableInfo()));
SerializedDeclUSRTable::Create(base + tableOffset, base + sizeof(uint32_t),
base));
}
bool ModuleFile::readDeclLocsBlock(llvm::BitstreamCursor &cursor) {
@@ -2364,7 +2366,8 @@ Optional<CommentInfo> ModuleFile::getCommentForDecl(const Decl *D) const {
return getCommentForDeclByUSR(USRBuffer.str());
}
Optional<BasicDeclLocs> ModuleFile::getBasicDeclLocsForDecl(const Decl *D) const {
Optional<BasicDeclLocs>
ModuleFile::getBasicDeclLocsForDecl(const Decl *D) const {
assert(D);
// Keep these as assertions instead of early exits to ensure that we are not
@@ -2375,6 +2378,9 @@ Optional<BasicDeclLocs> ModuleFile::getBasicDeclLocsForDecl(const Decl *D) const
"Decl is from a different serialized file");
if (!DeclUSRsTable)
return None;
// Future compilers may not provide BasicDeclLocsData anymore.
if (BasicDeclLocsData.empty())
return None;
// Compute the USR.
llvm::SmallString<128> USRBuffer;
llvm::raw_svector_ostream OS(USRBuffer);
@@ -2394,12 +2400,11 @@ Optional<BasicDeclLocs> ModuleFile::getBasicDeclLocsForDecl(const Decl *D) const
assert(RecordOffset < BasicDeclLocsData.size());
assert(BasicDeclLocsData.size() % RecordSize == 0);
BasicDeclLocs Result;
auto *Record = reinterpret_cast<const uint32_t*>(BasicDeclLocsData.data() + RecordOffset);
auto *Record = BasicDeclLocsData.data() + RecordOffset;
auto ReadNext = [&Record]() {
uint32_t Result = *Record;
++ Record;
return Result;
return endian::readNext<uint32_t, little, unaligned>(Record);
};
auto FilePath = SourceLocsTextData.substr(ReadNext());
size_t TerminatorOffset = FilePath.find('\0');
assert(TerminatorOffset != StringRef::npos && "unterminated string data");

View File

@@ -411,6 +411,13 @@ private:
llvm::OnDiskIterableChainedHashTable<DeclUSRTableInfo>;
std::unique_ptr<SerializedDeclUSRTable> DeclUSRsTable;
/// A blob of 0 terminated string segments referenced in \c SourceLocsTextData
StringRef SourceLocsTextData;
/// An array of fixed size source location data for each USR appearing in
/// \c DeclUSRsTable.
StringRef BasicDeclLocsData;
struct ModuleBits {
/// The decl ID of the main class in this module file, if it has one.
unsigned EntryPointDeclID : 31;
@@ -557,14 +564,6 @@ private:
/// Returns false if there was an error.
bool readModuleSourceInfoIfPresent();
/// Read an on-disk decl hash table stored in
/// \c sourceinfo_block::BasicDeclLocsLayout format.
StringRef BasicDeclLocsData;
/// Read an on-disk decl hash table stored in
/// \c sourceinfo_block::SourceFilePathsLayout format.
StringRef SourceLocsTextData;
/// Read an on-disk decl hash table stored in
/// \c sourceinfo_block::DeclUSRSLayout format.
std::unique_ptr<SerializedDeclUSRTable>

View File

@@ -642,14 +642,23 @@ enum BlockID {
/// The module source location container block, which contains all other
/// source location blocks.
///
/// This is part of a stable format and must not be renumbered!
/// This is part of a stable format and should not be renumbered.
///
/// Though we strive to keep the format stable, breaking the format of
/// .swiftsourceinfo doesn't have consequences as serious as breaking the
/// format of .swiftdoc because .swiftsourceinfo file is for local development
/// use only.
MODULE_SOURCEINFO_BLOCK_ID = 192,
/// The source location block, which contains decl locations.
///
/// This is part of a stable format and must not be renumbered!
/// This is part of a stable format and should not be renumbered.
///
/// \sa sourceinfo_block
/// Though we strive to keep the format stable, breaking the format of
/// .swiftsourceinfo doesn't have consequences as serious as breaking the format
/// of .swiftdoc because .swiftsourceinfo file is for local development use only.
///
/// \sa decl_locs_block
DECL_LOCS_BLOCK_ID,
};

View File

@@ -13,7 +13,6 @@
#include "DocFormat.h"
#include "Serialization.h"
#include "SourceInfoFormat.h"
#include "swift/Basic/Defer.h"
#include "swift/AST/ASTContext.h"
#include "swift/AST/ASTWalker.h"
#include "swift/AST/DiagnosticsCommon.h"
@@ -21,7 +20,9 @@
#include "swift/AST/ParameterList.h"
#include "swift/AST/SourceFile.h"
#include "swift/AST/USRGeneration.h"
#include "swift/Basic/Defer.h"
#include "swift/Basic/SourceManager.h"
#include "llvm/ADT/StringSet.h"
#include "llvm/Support/DJB.h"
#include "llvm/Support/EndianStream.h"
#include "llvm/Support/OnDiskHashTable.h"
@@ -546,25 +547,29 @@ public:
out << key;
}
void EmitData(raw_ostream &out, key_type_ref key, data_type_ref data, unsigned len) {
void EmitData(raw_ostream &out, key_type_ref key, data_type_ref data,
unsigned len) {
endian::Writer writer(out, little);
writer.write<uint32_t>(data);
}
};
class DeclUSRsTableWriter {
llvm::StringMap<uint32_t> USRMap;
llvm::StringSet<> USRs;
llvm::OnDiskChainedHashTableGenerator<USRTableInfo> generator;
uint32_t CurId = 0;
public:
uint32_t peekNextId() const { return CurId; }
Optional<uint32_t> getNewUSRID(StringRef USR) {
if (USRMap.find(USR) == USRMap.end()) {
generator.insert(USRMap.insert(std::make_pair(USR, CurId)).first->getKey(), CurId);
++CurId;
return USRMap.find(USR)->second;
}
uint32_t peekNextId() const { return USRs.size(); }
Optional<uint32_t> getNewUSRId(StringRef USR) {
// Attempt to insert the USR into the StringSet.
auto It = USRs.insert(USR);
// If the USR exists in the StringSet, return None.
if (!It.second)
return None;
auto Id = USRs.size() - 1;
// We have to insert the USR from the StringSet because it's where the
// memory is owned.
generator.insert(It.first->getKey(), Id);
return Id;
}
void emitUSRsRecord(llvm::BitstreamWriter &out) {
decl_locs_block::DeclUSRSLayout USRsList(out);
@@ -606,10 +611,11 @@ struct BasicDeclLocsTableWriter : public ASTWalker {
DeclUSRsTableWriter &USRWriter;
StringWriter &FWriter;
BasicDeclLocsTableWriter(DeclUSRsTableWriter &USRWriter,
StringWriter &FWriter): USRWriter(USRWriter), FWriter(FWriter) {}
StringWriter &FWriter): USRWriter(USRWriter),
FWriter(FWriter) {}
std::pair<bool, Stmt *> walkToStmtPre(Stmt *S) override { return { false, S }; }
std::pair<bool, Expr *> walkToExprPre(Expr *E) override { return { false, E }; }
std::pair<bool, Stmt *> walkToStmtPre(Stmt *S) override { return { false, S };}
std::pair<bool, Expr *> walkToExprPre(Expr *E) override { return { false, E };}
bool walkToTypeLocPre(TypeLoc &TL) override { return false; }
bool walkToTypeReprPre(TypeRepr *T) override { return false; }
bool walkToParameterListPre(ParameterList *PL) override { return false; }
@@ -632,7 +638,7 @@ writer.write<uint32_t>(data.X.Column);
llvm::raw_svector_ostream OS(Buffer);
if (ide::printDeclUSR(D, OS))
return None;
return USRWriter.getNewUSRID(OS.str());
return USRWriter.getNewUSRId(OS.str());
}
LineColumn getLineColumn(SourceManager &SM, SourceLoc Loc) {
@@ -693,13 +699,13 @@ Result.X.Column = Locs->X.Column;
bool walkToDeclPre(Decl *D) override {
SWIFT_DEFER {
assert(USRWriter.peekNextId() * sizeof(DeclLocationsTableData) == Buffer.size() &&
assert(USRWriter.peekNextId() * sizeof(DeclLocationsTableData)
== Buffer.size() &&
"USR Id has a one-to-one mapping with DeclLocationsTableData");
};
// We shouldn't expose any Decls that .swiftdoc file isn't willing to expose.
// .swiftdoc doesn't include comments for double underscored symbols, but for .swiftsourceinfo,
// having the source location for these symbols isn't a concern becuase these
// symbols are in .swiftinterface anyway.
// .swiftdoc doesn't include comments for double underscored symbols, but
// for .swiftsourceinfo, having the source location for these symbols isn't
// a concern becuase these symbols are in .swiftinterface anyway.
if (!shouldIncludeDecl(D, /*ExcludeDoubleUnderscore*/false))
return false;
if (!shouldSerializeSourceLoc(D))
@@ -718,7 +724,8 @@ Result.X.Column = Locs->X.Column;
};
static void emitBasicLocsRecord(llvm::BitstreamWriter &Out,
ModuleOrSourceFile MSF, DeclUSRsTableWriter &USRWriter,
ModuleOrSourceFile MSF,
DeclUSRsTableWriter &USRWriter,
StringWriter &FWriter) {
assert(MSF);
const decl_locs_block::BasicDeclLocsLayout DeclLocsList(Out);
@@ -773,7 +780,8 @@ public:
control_block::TargetLayout Target(Out);
auto& LangOpts = M->getASTContext().LangOpts;
Metadata.emit(ScratchRecord, SWIFTSOURCEINFO_VERSION_MAJOR, SWIFTSOURCEINFO_VERSION_MINOR,
Metadata.emit(ScratchRecord, SWIFTSOURCEINFO_VERSION_MAJOR,
SWIFTSOURCEINFO_VERSION_MINOR,
/*short version string length*/0, /*compatibility length*/0,
version::getSwiftFullVersion(LangOpts.EffectiveLanguageVersion));
@@ -783,7 +791,8 @@ public:
}
};
}
void serialization::writeSourceInfoToStream(raw_ostream &os, ModuleOrSourceFile DC) {
void serialization::writeSourceInfoToStream(raw_ostream &os,
ModuleOrSourceFile DC) {
assert(DC);
SourceInfoSerializer S{SWIFTSOURCEINFO_SIGNATURE, DC};
// FIXME: This is only really needed for debugging. We don't actually use it.
@@ -797,10 +806,11 @@ void serialization::writeSourceInfoToStream(raw_ostream &os, ModuleOrSourceFile
StringWriter FPWriter;
emitBasicLocsRecord(S.Out, DC, USRWriter, FPWriter);
// Emit USR table mapping from a USR to USR Id.
// The basic locs record uses USR Id instead of actual USR, so that we don't need to repeat
// USR texts for newly added records.
// The basic locs record uses USR Id instead of actual USR, so that we
// don't need to repeat USR texts for newly added records.
USRWriter.emitUSRsRecord(S.Out);
// A blob of 0 terminated strings referenced by the location records, e.g. file paths.
// A blob of 0 terminated strings referenced by the location records,
// e.g. file paths.
FPWriter.emitSourceFilesRecord(S.Out);
}
}

View File

@@ -263,43 +263,35 @@ std::error_code SerializedModuleLoaderBase::openModuleDocFile(
return std::error_code();
}
std::error_code
SerializedModuleLoaderBase::openModuleSourceInfoFile(AccessPathElem ModuleID,
void
SerializedModuleLoaderBase::openModuleSourceInfoFileIfPresent(
AccessPathElem ModuleID,
StringRef ModulePath,
StringRef ModuleSourceInfoFilename,
std::unique_ptr<llvm::MemoryBuffer> *ModuleSourceInfoBuffer) {
if (!ModuleSourceInfoBuffer)
return std::error_code();
return;
llvm::vfs::FileSystem &FS = *Ctx.SourceMgr.getFileSystem();
{
llvm::SmallString<128> ProjectPath(ModulePath);
llvm::sys::path::remove_filename(ProjectPath);
llvm::sys::path::append(ProjectPath, "Project");
llvm::sys::path::append(ProjectPath, ModuleSourceInfoFilename);
llvm::SmallString<128> PathWithoutProjectDir(ModulePath);
llvm::sys::path::replace_extension(PathWithoutProjectDir,
file_types::getExtension(file_types::TY_SwiftSourceInfoFile));
llvm::SmallString<128> PathWithProjectDir = PathWithoutProjectDir.str();
StringRef FileName = llvm::sys::path::filename(PathWithoutProjectDir);
llvm::sys::path::remove_filename(PathWithProjectDir);
llvm::sys::path::append(PathWithProjectDir, "Project");
llvm::sys::path::append(PathWithProjectDir, FileName);
// Try to open the module source info file. If it does not exist, ignore
// the error. However, pass though all other errors.
if (llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>> ModuleSourceInfoOrErr =
FS.getBufferForFile(ProjectPath)) {
// Try to open the module source info file from the "Project" directory.
// If it does not exist, ignore the error.
if (auto ModuleSourceInfoOrErr = FS.getBufferForFile(PathWithProjectDir)) {
*ModuleSourceInfoBuffer = std::move(*ModuleSourceInfoOrErr);
return std::error_code();
return;
}
}
{
llvm::SmallString<128> NonProjectPath(ModulePath);
llvm::sys::path::remove_filename(NonProjectPath);
llvm::sys::path::append(NonProjectPath, ModuleSourceInfoFilename);
// Try to open the module source info file adjacent to the .swiftmodule file.
if (llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>> ModuleSourceInfoOrErr =
FS.getBufferForFile(NonProjectPath)) {
if (auto ModuleSourceInfoOrErr = FS.getBufferForFile(PathWithoutProjectDir)) {
*ModuleSourceInfoBuffer = std::move(*ModuleSourceInfoOrErr);
return std::error_code();
return;
}
}
// Failing to load .swiftsourceinfo file isn't critical, so don't return any errors.
return std::error_code();
}
std::error_code SerializedModuleLoaderBase::openModuleFiles(
@@ -335,16 +327,15 @@ std::error_code SerializedModuleLoaderBase::openModuleFiles(
if (!ModuleOrErr)
return ModuleOrErr.getError();
// Open .swiftsourceinfo file if it's present.
openModuleSourceInfoFileIfPresent(ModuleID, ModulePath,
ModuleSourceInfoFileName,
ModuleSourceInfoBuffer);
auto ModuleDocErr =
openModuleDocFile(ModuleID, ModuleDocPath, ModuleDocBuffer);
if (ModuleDocErr)
return ModuleDocErr;
auto ModuleSourceInfoErr =
openModuleSourceInfoFile(ModuleID, ModulePath, ModuleSourceInfoFileName, ModuleSourceInfoBuffer);
if (ModuleSourceInfoErr)
return ModuleSourceInfoErr;
*ModuleBuffer = std::move(ModuleOrErr.get());
return std::error_code();

View File

@@ -31,13 +31,13 @@ using llvm::BCRecordLayout;
using llvm::BCVBR;
/// Magic number for serialized source info files.
const unsigned char SWIFTSOURCEINFO_SIGNATURE[] = { 0xD6, 0x9C, 0xB7, 0x23 };
const unsigned char SWIFTSOURCEINFO_SIGNATURE[] = { 0xF0, 0x9F, 0x8F, 0x8E };
/// Serialized sourceinfo format major version number.
///
/// Increment this value when making a backwards-incompatible change, i.e. where
/// an \e old compiler will \e not be able to read the new format. This should
/// be rare. When incrementing this value, reset SWIFTDOC_VERSION_MINOR to 0.
/// be rare. When incrementing this value, reset SWIFTSOURCEINFO_VERSION_MINOR to 0.
///
/// See docs/StableBitcode.md for information on how to make
/// backwards-compatible changes using the LLVM bitcode format.
@@ -56,11 +56,14 @@ const uint32_t SWIFTSOURCEINFO_HASH_SEED = 5387;
/// The record types within the DECL_LOCS block.
///
/// Be very careful when changing this block; it must remain
/// backwards-compatible. Adding new records is okay---they will be ignored---
/// but modifying existing ones must be done carefully. You may need to update
/// the version when you do so. See docs/StableBitcode.md for information on how
/// to make backwards-compatible changes using the LLVM bitcode format.
/// Though we strive to keep the format stable, breaking the format of
/// .swiftsourceinfo doesn't have consequences as serious as breaking the format
/// of .swiftdoc, because .swiftsourceinfo file is for local development use only.
///
/// When changing this block, backwards-compatible changes are prefered.
/// You may need to update the version when you do so. See docs/StableBitcode.md
/// for information on how to make backwards-compatible changes using the LLVM
/// bitcode format.
///
/// \sa DECL_LOCS_BLOCK_ID
namespace decl_locs_block {