mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
[Serialization] Serialize/deserialize source file list
This commit is contained in:
@@ -402,6 +402,9 @@ public:
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
virtual void
|
||||||
|
collectSourceFileNames(llvm::function_ref<void(StringRef)> callback) const {}
|
||||||
|
|
||||||
static bool classof(const FileUnit *file) {
|
static bool classof(const FileUnit *file) {
|
||||||
return file->getKind() == FileUnitKind::SerializedAST ||
|
return file->getKind() == FileUnitKind::SerializedAST ||
|
||||||
file->getKind() == FileUnitKind::ClangModule ||
|
file->getKind() == FileUnitKind::ClangModule ||
|
||||||
|
|||||||
@@ -728,6 +728,8 @@ public:
|
|||||||
return ReverseFullNameIterator(this);
|
return ReverseFullNameIterator(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void collectSourceFileNames(llvm::function_ref<void(StringRef)> callback);
|
||||||
|
|
||||||
SourceRange getSourceRange() const { return SourceRange(); }
|
SourceRange getSourceRange() const { return SourceRange(); }
|
||||||
|
|
||||||
static bool classof(const DeclContext *DC) {
|
static bool classof(const DeclContext *DC) {
|
||||||
|
|||||||
@@ -446,6 +446,9 @@ public:
|
|||||||
|
|
||||||
StringRef getTargetTriple() const;
|
StringRef getTargetTriple() const;
|
||||||
|
|
||||||
|
virtual void collectSourceFileNames(
|
||||||
|
llvm::function_ref<void(StringRef)>) const override;
|
||||||
|
|
||||||
static bool classof(const FileUnit *file) {
|
static bool classof(const FileUnit *file) {
|
||||||
return file->getKind() == FileUnitKind::SerializedAST;
|
return file->getKind() == FileUnitKind::SerializedAST;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1514,6 +1514,17 @@ const clang::Module *ModuleDecl::findUnderlyingClangModule() const {
|
|||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ModuleDecl::collectSourceFileNames(
|
||||||
|
llvm::function_ref<void(StringRef)> callback) {
|
||||||
|
for (FileUnit *fileUnit : getFiles()) {
|
||||||
|
if (SourceFile *SF = dyn_cast<SourceFile>(fileUnit)) {
|
||||||
|
callback(SF->getFilename());
|
||||||
|
} else if (auto *serialized = dyn_cast<LoadedFile>(fileUnit)) {
|
||||||
|
serialized->collectSourceFileNames(callback);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
// Cross-Import Overlays
|
// Cross-Import Overlays
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
|
|||||||
@@ -959,6 +959,24 @@ Optional<CommentInfo> ModuleFile::getCommentForDecl(const Decl *D) const {
|
|||||||
return getCommentForDeclByUSR(USRBuffer.str());
|
return getCommentForDeclByUSR(USRBuffer.str());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ModuleFile::collectSourceFileNames(
|
||||||
|
llvm::function_ref<void(StringRef)> callback) const {
|
||||||
|
if (Core->SourceFileListData.empty())
|
||||||
|
return;
|
||||||
|
assert(!Core->SourceLocsTextData.empty());
|
||||||
|
|
||||||
|
auto *Cursor = Core->SourceFileListData.bytes_begin();
|
||||||
|
auto *End = Core->SourceFileListData.bytes_end();
|
||||||
|
while (Cursor < End) {
|
||||||
|
auto fileID = endian::readNext<uint32_t, little, unaligned>(Cursor);
|
||||||
|
assert(fileID < Core->SourceLocsTextData.size());
|
||||||
|
auto filePath = Core->SourceLocsTextData.substr(fileID);
|
||||||
|
size_t terminatorOffset = filePath.find('\0');
|
||||||
|
filePath = filePath.slice(0, terminatorOffset);
|
||||||
|
callback(filePath);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Optional<BasicDeclLocs>
|
Optional<BasicDeclLocs>
|
||||||
ModuleFile::getBasicDeclLocsForDecl(const Decl *D) const {
|
ModuleFile::getBasicDeclLocsForDecl(const Decl *D) const {
|
||||||
assert(D);
|
assert(D);
|
||||||
|
|||||||
@@ -694,6 +694,7 @@ public:
|
|||||||
Optional<BasicDeclLocs> getBasicDeclLocsForDecl(const Decl *D) const;
|
Optional<BasicDeclLocs> getBasicDeclLocsForDecl(const Decl *D) const;
|
||||||
Identifier getDiscriminatorForPrivateValue(const ValueDecl *D);
|
Identifier getDiscriminatorForPrivateValue(const ValueDecl *D);
|
||||||
Optional<Fingerprint> loadFingerprint(const IterableDeclContext *IDC) const;
|
Optional<Fingerprint> loadFingerprint(const IterableDeclContext *IDC) const;
|
||||||
|
void collectSourceFileNames(llvm::function_ref<void(StringRef)> callback) const;
|
||||||
|
|
||||||
|
|
||||||
// MARK: Deserialization interface
|
// MARK: Deserialization interface
|
||||||
|
|||||||
@@ -974,6 +974,9 @@ bool ModuleFileSharedCore::readDeclLocsBlock(llvm::BitstreamCursor &cursor) {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
switch (*kind) {
|
switch (*kind) {
|
||||||
|
case decl_locs_block::SOURCE_FILE_LIST:
|
||||||
|
SourceFileListData = blobData;
|
||||||
|
break;
|
||||||
case decl_locs_block::BASIC_DECL_LOCS:
|
case decl_locs_block::BASIC_DECL_LOCS:
|
||||||
BasicDeclLocsData = blobData;
|
BasicDeclLocsData = blobData;
|
||||||
break;
|
break;
|
||||||
|
|||||||
@@ -289,6 +289,9 @@ private:
|
|||||||
/// A blob of 0 terminated string segments referenced in \c SourceLocsTextData
|
/// A blob of 0 terminated string segments referenced in \c SourceLocsTextData
|
||||||
StringRef SourceLocsTextData;
|
StringRef SourceLocsTextData;
|
||||||
|
|
||||||
|
/// A blob of source file list.
|
||||||
|
StringRef SourceFileListData;
|
||||||
|
|
||||||
/// An array of fixed size source location data for each USR appearing in
|
/// An array of fixed size source location data for each USR appearing in
|
||||||
/// \c DeclUSRsTable.
|
/// \c DeclUSRsTable.
|
||||||
StringRef BasicDeclLocsData;
|
StringRef BasicDeclLocsData;
|
||||||
|
|||||||
@@ -783,6 +783,46 @@ static void emitBasicLocsRecord(llvm::BitstreamWriter &Out,
|
|||||||
DeclLocsList.emit(scratch, Writer.Buffer);
|
DeclLocsList.emit(scratch, Writer.Buffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void emitFileListRecord(llvm::BitstreamWriter &Out,
|
||||||
|
ModuleOrSourceFile MSF, StringWriter &FWriter) {
|
||||||
|
assert(MSF);
|
||||||
|
|
||||||
|
struct SourceFileListWriter {
|
||||||
|
StringWriter &FWriter;
|
||||||
|
|
||||||
|
llvm::SmallString<1024> Buffer;
|
||||||
|
llvm::StringSet<> seenFilenames;
|
||||||
|
|
||||||
|
void emitFilename(StringRef filename) {
|
||||||
|
if (filename.empty())
|
||||||
|
return;
|
||||||
|
llvm::SmallString<128> absolutePath = filename;
|
||||||
|
llvm::sys::fs::make_absolute(absolutePath);
|
||||||
|
if (!seenFilenames.insert(absolutePath).second)
|
||||||
|
return;
|
||||||
|
|
||||||
|
auto fileID = FWriter.getTextOffset(absolutePath);
|
||||||
|
llvm::raw_svector_ostream out(Buffer);
|
||||||
|
endian::Writer writer(out, little);
|
||||||
|
writer.write<uint32_t>(fileID);
|
||||||
|
}
|
||||||
|
|
||||||
|
SourceFileListWriter(StringWriter &FWriter) : FWriter(FWriter) {}
|
||||||
|
} writer(FWriter);
|
||||||
|
|
||||||
|
if (SourceFile *SF = MSF.dyn_cast<SourceFile *>()) {
|
||||||
|
writer.emitFilename(SF->getFilename());
|
||||||
|
} else {
|
||||||
|
auto *M = MSF.get<ModuleDecl *>();
|
||||||
|
M->collectSourceFileNames(
|
||||||
|
[&](StringRef filename) { writer.emitFilename(filename); });
|
||||||
|
}
|
||||||
|
|
||||||
|
const decl_locs_block::SourceFileListLayout FileList(Out);
|
||||||
|
SmallVector<uint64_t, 8> scratch;
|
||||||
|
FileList.emit(scratch, writer.Buffer);
|
||||||
|
}
|
||||||
|
|
||||||
class SourceInfoSerializer : public SerializerBase {
|
class SourceInfoSerializer : public SerializerBase {
|
||||||
public:
|
public:
|
||||||
using SerializerBase::SerializerBase;
|
using SerializerBase::SerializerBase;
|
||||||
@@ -807,6 +847,7 @@ public:
|
|||||||
BLOCK_RECORD(control_block, TARGET);
|
BLOCK_RECORD(control_block, TARGET);
|
||||||
|
|
||||||
BLOCK(DECL_LOCS_BLOCK);
|
BLOCK(DECL_LOCS_BLOCK);
|
||||||
|
BLOCK_RECORD(decl_locs_block, SOURCE_FILE_LIST);
|
||||||
BLOCK_RECORD(decl_locs_block, BASIC_DECL_LOCS);
|
BLOCK_RECORD(decl_locs_block, BASIC_DECL_LOCS);
|
||||||
BLOCK_RECORD(decl_locs_block, DECL_USRS);
|
BLOCK_RECORD(decl_locs_block, DECL_USRS);
|
||||||
BLOCK_RECORD(decl_locs_block, TEXT_DATA);
|
BLOCK_RECORD(decl_locs_block, TEXT_DATA);
|
||||||
@@ -849,6 +890,7 @@ void serialization::writeSourceInfoToStream(raw_ostream &os,
|
|||||||
DeclUSRsTableWriter USRWriter;
|
DeclUSRsTableWriter USRWriter;
|
||||||
StringWriter FPWriter;
|
StringWriter FPWriter;
|
||||||
DocRangeWriter DocWriter;
|
DocRangeWriter DocWriter;
|
||||||
|
emitFileListRecord(S.Out, DC, FPWriter);
|
||||||
emitBasicLocsRecord(S.Out, DC, USRWriter, FPWriter, DocWriter);
|
emitBasicLocsRecord(S.Out, DC, USRWriter, FPWriter, DocWriter);
|
||||||
// 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
|
// The basic locs record uses USR Id instead of actual USR, so that we
|
||||||
|
|||||||
@@ -1327,3 +1327,8 @@ SerializedASTFile::getDiscriminatorForPrivateValue(const ValueDecl *D) const {
|
|||||||
assert(!discriminator.empty() && "no discriminator found for value");
|
assert(!discriminator.empty() && "no discriminator found for value");
|
||||||
return discriminator;
|
return discriminator;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SerializedASTFile::collectSourceFileNames(
|
||||||
|
llvm::function_ref<void(StringRef)> callback) const {
|
||||||
|
File.collectSourceFileNames(callback);
|
||||||
|
}
|
||||||
|
|||||||
@@ -49,7 +49,7 @@ const uint16_t SWIFTSOURCEINFO_VERSION_MAJOR = 2;
|
|||||||
/// interesting to test for. A backwards-compatible change is one where an \e
|
/// interesting to test for. A backwards-compatible change is one where an \e
|
||||||
/// old compiler can read the new format without any problems (usually by
|
/// old compiler can read the new format without any problems (usually by
|
||||||
/// ignoring new information).
|
/// ignoring new information).
|
||||||
const uint16_t SWIFTSOURCEINFO_VERSION_MINOR = 0; // Last change: add doc comment ranges
|
const uint16_t SWIFTSOURCEINFO_VERSION_MINOR = 1; // Last change: add source file list
|
||||||
|
|
||||||
/// The hash seed used for the string hashes(llvm::djbHash) in a .swiftsourceinfo file.
|
/// The hash seed used for the string hashes(llvm::djbHash) in a .swiftsourceinfo file.
|
||||||
const uint32_t SWIFTSOURCEINFO_HASH_SEED = 5387;
|
const uint32_t SWIFTSOURCEINFO_HASH_SEED = 5387;
|
||||||
@@ -72,6 +72,7 @@ namespace decl_locs_block {
|
|||||||
DECL_USRS,
|
DECL_USRS,
|
||||||
TEXT_DATA,
|
TEXT_DATA,
|
||||||
DOC_RANGES,
|
DOC_RANGES,
|
||||||
|
SOURCE_FILE_LIST,
|
||||||
};
|
};
|
||||||
|
|
||||||
using BasicDeclLocsLayout = BCRecordLayout<
|
using BasicDeclLocsLayout = BCRecordLayout<
|
||||||
@@ -79,6 +80,11 @@ namespace decl_locs_block {
|
|||||||
BCBlob // an array of fixed size location data
|
BCBlob // an array of fixed size location data
|
||||||
>;
|
>;
|
||||||
|
|
||||||
|
using SourceFileListLayout = BCRecordLayout<
|
||||||
|
SOURCE_FILE_LIST, // record ID
|
||||||
|
BCBlob // An array of string offsets in TextDataLayout
|
||||||
|
>;
|
||||||
|
|
||||||
using DeclUSRSLayout = BCRecordLayout<
|
using DeclUSRSLayout = BCRecordLayout<
|
||||||
DECL_USRS, // record ID
|
DECL_USRS, // record ID
|
||||||
BCVBR<16>, // table offset within the blob (an llvm::OnDiskHashTable)
|
BCVBR<16>, // table offset within the blob (an llvm::OnDiskHashTable)
|
||||||
|
|||||||
@@ -2519,6 +2519,9 @@ static void printModuleMetadata(ModuleDecl *MD) {
|
|||||||
OS << "link library: " << lib.getName()
|
OS << "link library: " << lib.getName()
|
||||||
<< ", force load: " << (lib.shouldForceLoad() ? "true" : "false") << "\n";
|
<< ", force load: " << (lib.shouldForceLoad() ? "true" : "false") << "\n";
|
||||||
});
|
});
|
||||||
|
MD->collectSourceFileNames([&](StringRef filename) {
|
||||||
|
OS << filename << "\n";
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
static int doPrintModuleMetaData(const CompilerInvocation &InitInvok,
|
static int doPrintModuleMetaData(const CompilerInvocation &InitInvok,
|
||||||
|
|||||||
Reference in New Issue
Block a user