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,11 +89,11 @@ protected:
StringRef ModuleDocPath, StringRef ModuleDocPath,
std::unique_ptr<llvm::MemoryBuffer> *ModuleDocBuffer); std::unique_ptr<llvm::MemoryBuffer> *ModuleDocBuffer);
std::error_code void
openModuleSourceInfoFile(AccessPathElem ModuleID, openModuleSourceInfoFileIfPresent(AccessPathElem ModuleID,
StringRef ModulePath, StringRef ModulePath,
StringRef ModuleSourceInfoFileName, StringRef ModuleSourceInfoFileName,
std::unique_ptr<llvm::MemoryBuffer> *ModuleSourceInfoBuffer); std::unique_ptr<llvm::MemoryBuffer> *ModuleSourceInfoBuffer);
/// If the module loader subclass knows that all options have been tried for /// If the module loader subclass knows that all options have been tried for
/// loading an architecture-specific file out of a swiftmodule bundle, try /// loading an architecture-specific file out of a swiftmodule bundle, try

View File

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

View File

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

View File

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

View File

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

View File

@@ -411,6 +411,13 @@ private:
llvm::OnDiskIterableChainedHashTable<DeclUSRTableInfo>; llvm::OnDiskIterableChainedHashTable<DeclUSRTableInfo>;
std::unique_ptr<SerializedDeclUSRTable> DeclUSRsTable; 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 { struct ModuleBits {
/// The decl ID of the main class in this module file, if it has one. /// The decl ID of the main class in this module file, if it has one.
unsigned EntryPointDeclID : 31; unsigned EntryPointDeclID : 31;
@@ -557,14 +564,6 @@ private:
/// Returns false if there was an error. /// Returns false if there was an error.
bool readModuleSourceInfoIfPresent(); 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 /// Read an on-disk decl hash table stored in
/// \c sourceinfo_block::DeclUSRSLayout format. /// \c sourceinfo_block::DeclUSRSLayout format.
std::unique_ptr<SerializedDeclUSRTable> std::unique_ptr<SerializedDeclUSRTable>

View File

@@ -642,14 +642,23 @@ enum BlockID {
/// The module source location container block, which contains all other /// The module source location container block, which contains all other
/// source location blocks. /// 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, MODULE_SOURCEINFO_BLOCK_ID = 192,
/// The source location block, which contains decl locations. /// 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, DECL_LOCS_BLOCK_ID,
}; };

View File

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

View File

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

View File

@@ -31,13 +31,13 @@ using llvm::BCRecordLayout;
using llvm::BCVBR; using llvm::BCVBR;
/// Magic number for serialized source info files. /// 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. /// Serialized sourceinfo format major version number.
/// ///
/// Increment this value when making a backwards-incompatible change, i.e. where /// 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 /// 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 /// See docs/StableBitcode.md for information on how to make
/// backwards-compatible changes using the LLVM bitcode format. /// 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. /// The record types within the DECL_LOCS block.
/// ///
/// Be very careful when changing this block; it must remain /// Though we strive to keep the format stable, breaking the format of
/// backwards-compatible. Adding new records is okay---they will be ignored--- /// .swiftsourceinfo doesn't have consequences as serious as breaking the format
/// but modifying existing ones must be done carefully. You may need to update /// of .swiftdoc, because .swiftsourceinfo file is for local development use only.
/// the version when you do so. See docs/StableBitcode.md for information on how ///
/// to make backwards-compatible changes using the LLVM bitcode format. /// 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 /// \sa DECL_LOCS_BLOCK_ID
namespace decl_locs_block { namespace decl_locs_block {