mirror of
https://github.com/apple/swift.git
synced 2025-12-21 12:14:44 +01:00
SerializeLoc: address more comments from Jordan. NFC
This commit is contained in:
@@ -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
|
||||||
|
|||||||
@@ -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,
|
||||||
|
|||||||
@@ -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;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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.
|
||||||
|
|||||||
@@ -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)
|
||||||
|
|||||||
@@ -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>
|
||||||
|
|||||||
@@ -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,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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();
|
||||||
|
|||||||
@@ -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 {
|
||||||
|
|||||||
Reference in New Issue
Block a user