Skip to content

Commit 91f0804

Browse files
committed
serialization: serialize actual source location information to .swiftsourceinfo file
1 parent 33770fa commit 91f0804

File tree

22 files changed

+1163
-132
lines changed

22 files changed

+1163
-132
lines changed

include/swift/AST/FileUnit.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -132,6 +132,10 @@ class FileUnit : public DeclContext {
132132
return None;
133133
}
134134

135+
virtual Optional<BasicDeclLocs> getBasicLocsForDecl(const Decl *D) const {
136+
return None;
137+
}
138+
135139
virtual void collectAllGroups(std::vector<StringRef> &Names) const {}
136140

137141
/// Returns an implementation-defined "discriminator" for \p D, which

include/swift/AST/RawComment.h

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,19 @@ struct CommentInfo {
7878
uint32_t SourceOrder;
7979
};
8080

81+
struct LineColumn {
82+
uint32_t Line;
83+
uint32_t Column;
84+
};
85+
86+
struct BasicDeclLocs {
87+
StringRef SourceFilePath;
88+
Optional<LineColumn> Loc;
89+
Optional<LineColumn> NameLoc;
90+
Optional<LineColumn> StartLoc;
91+
Optional<LineColumn> EndLoc;
92+
};
93+
8194
} // namespace swift
8295

8396
#endif // LLVM_SWIFT_AST_RAW_COMMENT_H

include/swift/AST/USRGeneration.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
#include "swift/Basic/LLVM.h"
1717

1818
namespace swift {
19+
class Decl;
1920
class AbstractStorageDecl;
2021
class ValueDecl;
2122
class ExtensionDecl;
@@ -50,6 +51,10 @@ bool printAccessorUSR(const AbstractStorageDecl *D, AccessorKind AccKind,
5051
/// \returns true if it failed, false on success.
5152
bool printExtensionUSR(const ExtensionDecl *ED, raw_ostream &OS);
5253

54+
/// Prints out the Decl USRs suitable for keys .swiftdoc and .swiftsourceinfo files.
55+
/// \returns true if it failed, false on success.
56+
bool printDeclUSRForModuleDoc(const Decl *D, raw_ostream &OS);
57+
5358
} // namespace ide
5459
} // namespace swift
5560

include/swift/Frontend/Frontend.h

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -395,6 +395,7 @@ class CompilerInstance {
395395
struct PartialModuleInputs {
396396
std::unique_ptr<llvm::MemoryBuffer> ModuleBuffer;
397397
std::unique_ptr<llvm::MemoryBuffer> ModuleDocBuffer;
398+
std::unique_ptr<llvm::MemoryBuffer> ModuleSourceInfoBuffer;
398399
};
399400

400401
/// Contains \c MemoryBuffers for partial serialized module files and
@@ -555,20 +556,29 @@ class CompilerInstance {
555556

556557
Optional<unsigned> getRecordedBufferID(const InputFile &input, bool &failed);
557558

559+
struct ModuleBuffers {
560+
std::unique_ptr<llvm::MemoryBuffer> ModuleBuffer;
561+
std::unique_ptr<llvm::MemoryBuffer> ModuleDocBuffer;
562+
std::unique_ptr<llvm::MemoryBuffer> ModuleSourceInfoBuffer;
563+
};
564+
558565
/// Given an input file, return a buffer to use for its contents,
559566
/// and a buffer for the corresponding module doc file if one exists.
560567
/// On failure, return a null pointer for the first element of the returned
561568
/// pair.
562-
std::pair<std::unique_ptr<llvm::MemoryBuffer>,
563-
std::unique_ptr<llvm::MemoryBuffer>>
564-
getInputBufferAndModuleDocBufferIfPresent(const InputFile &input);
569+
ModuleBuffers getInputBuffersIfPresent(const InputFile &input);
565570

566571
/// Try to open the module doc file corresponding to the input parameter.
567572
/// Return None for error, nullptr if no such file exists, or the buffer if
568573
/// one was found.
569574
Optional<std::unique_ptr<llvm::MemoryBuffer>>
570575
openModuleDoc(const InputFile &input);
571576

577+
/// Try to open the module source info file corresponding to the input parameter.
578+
/// Return None for error, nullptr if no such file exists, or the buffer if
579+
/// one was found.
580+
Optional<std::unique_ptr<llvm::MemoryBuffer>>
581+
openModuleSourceInfo(const InputFile &input);
572582
public:
573583
/// Parses and type-checks all input files.
574584
void performSema();

include/swift/Frontend/ModuleInterfaceLoader.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -149,8 +149,10 @@ class ModuleInterfaceLoader : public SerializedModuleLoaderBase {
149149
std::error_code findModuleFilesInDirectory(
150150
AccessPathElem ModuleID, StringRef DirPath, StringRef ModuleFilename,
151151
StringRef ModuleDocFilename,
152+
StringRef ModuleSourceInfoFilename,
152153
std::unique_ptr<llvm::MemoryBuffer> *ModuleBuffer,
153-
std::unique_ptr<llvm::MemoryBuffer> *ModuleDocBuffer) override;
154+
std::unique_ptr<llvm::MemoryBuffer> *ModuleDocBuffer,
155+
std::unique_ptr<llvm::MemoryBuffer> *ModuleSourceInfoBuffer) override;
154156

155157
bool isCached(StringRef DepPath) override;
156158

include/swift/Serialization/SerializedModuleLoader.h

Lines changed: 22 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@ class SerializedModuleLoaderBase : public ModuleLoader {
5353
bool findModule(AccessPathElem moduleID,
5454
std::unique_ptr<llvm::MemoryBuffer> *moduleBuffer,
5555
std::unique_ptr<llvm::MemoryBuffer> *moduleDocBuffer,
56+
std::unique_ptr<llvm::MemoryBuffer> *moduleSourceInfoBuffer,
5657
bool &isFramework, bool &isSystemModule);
5758

5859
/// Attempts to search the provided directory for a loadable serialized
@@ -70,20 +71,30 @@ class SerializedModuleLoaderBase : public ModuleLoader {
7071
virtual std::error_code findModuleFilesInDirectory(
7172
AccessPathElem ModuleID, StringRef DirPath, StringRef ModuleFilename,
7273
StringRef ModuleDocFilename,
74+
StringRef ModuleSourceInfoFilename,
7375
std::unique_ptr<llvm::MemoryBuffer> *ModuleBuffer,
74-
std::unique_ptr<llvm::MemoryBuffer> *ModuleDocBuffer) = 0;
76+
std::unique_ptr<llvm::MemoryBuffer> *ModuleDocBuffer,
77+
std::unique_ptr<llvm::MemoryBuffer> *ModuleSourceInfoBuffer) = 0;
7578

7679
std::error_code
7780
openModuleFiles(AccessPathElem ModuleID,
7881
StringRef ModulePath, StringRef ModuleDocPath,
82+
StringRef ModuleSourceInfoPath,
7983
std::unique_ptr<llvm::MemoryBuffer> *ModuleBuffer,
80-
std::unique_ptr<llvm::MemoryBuffer> *ModuleDocBuffer);
84+
std::unique_ptr<llvm::MemoryBuffer> *ModuleDocBuffer,
85+
std::unique_ptr<llvm::MemoryBuffer> *ModuleSourceInfoBuffer);
8186

8287
std::error_code
8388
openModuleDocFile(AccessPathElem ModuleID,
8489
StringRef ModuleDocPath,
8590
std::unique_ptr<llvm::MemoryBuffer> *ModuleDocBuffer);
8691

92+
std::error_code
93+
openModuleSourceInfoFile(AccessPathElem ModuleID,
94+
StringRef ModulePath,
95+
StringRef ModuleSourceInfoPath,
96+
std::unique_ptr<llvm::MemoryBuffer> *ModuleSourceInfoBuffer);
97+
8798
/// If the module loader subclass knows that all options have been tried for
8899
/// loading an architecture-specific file out of a swiftmodule bundle, try
89100
/// to list the architectures that \e are present.
@@ -116,6 +127,7 @@ class SerializedModuleLoaderBase : public ModuleLoader {
116127
FileUnit *loadAST(ModuleDecl &M, Optional<SourceLoc> diagLoc,
117128
std::unique_ptr<llvm::MemoryBuffer> moduleInputBuffer,
118129
std::unique_ptr<llvm::MemoryBuffer> moduleDocInputBuffer,
130+
std::unique_ptr<llvm::MemoryBuffer> moduleSourceInfoInputBuffer,
119131
bool isFramework, bool treatAsPartialModule);
120132

121133
/// Check whether the module with a given name can be imported without
@@ -163,8 +175,10 @@ class SerializedModuleLoader : public SerializedModuleLoaderBase {
163175
std::error_code findModuleFilesInDirectory(
164176
AccessPathElem ModuleID, StringRef DirPath, StringRef ModuleFilename,
165177
StringRef ModuleDocFilename,
178+
StringRef ModuleSourceInfoFilename,
166179
std::unique_ptr<llvm::MemoryBuffer> *ModuleBuffer,
167-
std::unique_ptr<llvm::MemoryBuffer> *ModuleDocBuffer) override;
180+
std::unique_ptr<llvm::MemoryBuffer> *ModuleDocBuffer,
181+
std::unique_ptr<llvm::MemoryBuffer> *ModuleSourceInfoBuffer) override;
168182

169183
bool maybeDiagnoseTargetMismatch(SourceLoc sourceLocation,
170184
StringRef moduleName,
@@ -203,8 +217,10 @@ class MemoryBufferSerializedModuleLoader : public SerializedModuleLoaderBase {
203217
std::error_code findModuleFilesInDirectory(
204218
AccessPathElem ModuleID, StringRef DirPath, StringRef ModuleFilename,
205219
StringRef ModuleDocFilename,
220+
StringRef ModuleSourceInfoFilename,
206221
std::unique_ptr<llvm::MemoryBuffer> *ModuleBuffer,
207-
std::unique_ptr<llvm::MemoryBuffer> *ModuleDocBuffer) override;
222+
std::unique_ptr<llvm::MemoryBuffer> *ModuleDocBuffer,
223+
std::unique_ptr<llvm::MemoryBuffer> *ModuleSourceInfoBuffer) override;
208224

209225
bool maybeDiagnoseTargetMismatch(SourceLoc sourceLocation,
210226
StringRef moduleName,
@@ -317,6 +333,8 @@ class SerializedASTFile final : public LoadedFile {
317333

318334
Optional<StringRef> getGroupNameByUSR(StringRef USR) const override;
319335

336+
Optional<BasicDeclLocs> getBasicLocsForDecl(const Decl *D) const override;
337+
320338
void collectAllGroups(std::vector<StringRef> &Names) const override;
321339

322340
virtual void getTopLevelDecls(SmallVectorImpl<Decl*> &results) const override;

lib/AST/USRGeneration.cpp

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -341,3 +341,19 @@ bool ide::printExtensionUSR(const ExtensionDecl *ED, raw_ostream &OS) {
341341
return true;
342342
}
343343

344+
bool ide::printDeclUSRForModuleDoc(const Decl *D, raw_ostream &OS) {
345+
if (D->isImplicit())
346+
return true;
347+
if (auto *VD = dyn_cast<ValueDecl>(D)) {
348+
if (ide::printDeclUSR(VD, OS)) {
349+
return true;
350+
}
351+
} else if (auto *ED = dyn_cast<ExtensionDecl>(D)) {
352+
if (ide::printExtensionUSR(ED, OS)) {
353+
return true;
354+
}
355+
} else {
356+
return true;
357+
}
358+
return false;
359+
}

lib/Frontend/Frontend.cpp

Lines changed: 41 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -470,38 +470,35 @@ Optional<unsigned> CompilerInstance::getRecordedBufferID(const InputFile &input,
470470
return existingBufferID;
471471
}
472472
}
473-
std::pair<std::unique_ptr<llvm::MemoryBuffer>,
474-
std::unique_ptr<llvm::MemoryBuffer>>
475-
buffers = getInputBufferAndModuleDocBufferIfPresent(input);
473+
auto buffers = getInputBuffersIfPresent(input);
476474

477-
if (!buffers.first) {
475+
if (!buffers.ModuleBuffer) {
478476
failed = true;
479477
return None;
480478
}
481479

482480
// FIXME: The fact that this test happens twice, for some cases,
483481
// suggests that setupInputs could use another round of refactoring.
484-
if (serialization::isSerializedAST(buffers.first->getBuffer())) {
482+
if (serialization::isSerializedAST(buffers.ModuleBuffer->getBuffer())) {
485483
PartialModules.push_back(
486-
{std::move(buffers.first), std::move(buffers.second)});
484+
{std::move(buffers.ModuleBuffer), std::move(buffers.ModuleDocBuffer),
485+
std::move(buffers.ModuleSourceInfoBuffer)});
487486
return None;
488487
}
489-
assert(buffers.second.get() == nullptr);
488+
assert(buffers.ModuleDocBuffer.get() == nullptr);
489+
assert(buffers.ModuleSourceInfoBuffer.get() == nullptr);
490490
// Transfer ownership of the MemoryBuffer to the SourceMgr.
491-
unsigned bufferID = SourceMgr.addNewSourceBuffer(std::move(buffers.first));
491+
unsigned bufferID = SourceMgr.addNewSourceBuffer(std::move(buffers.ModuleBuffer));
492492

493493
InputSourceCodeBufferIDs.push_back(bufferID);
494494
return bufferID;
495495
}
496496

497-
std::pair<std::unique_ptr<llvm::MemoryBuffer>,
498-
std::unique_ptr<llvm::MemoryBuffer>>
499-
CompilerInstance::getInputBufferAndModuleDocBufferIfPresent(
497+
CompilerInstance::ModuleBuffers CompilerInstance::getInputBuffersIfPresent(
500498
const InputFile &input) {
501499
if (auto b = input.buffer()) {
502-
return std::make_pair(llvm::MemoryBuffer::getMemBufferCopy(
503-
b->getBuffer(), b->getBufferIdentifier()),
504-
nullptr);
500+
return {llvm::MemoryBuffer::getMemBufferCopy(b->getBuffer(), b->getBufferIdentifier()),
501+
nullptr, nullptr};
505502
}
506503
// FIXME: Working with filenames is fragile, maybe use the real path
507504
// or have some kind of FileManager.
@@ -511,17 +508,37 @@ CompilerInstance::getInputBufferAndModuleDocBufferIfPresent(
511508
if (!inputFileOrErr) {
512509
Diagnostics.diagnose(SourceLoc(), diag::error_open_input_file, input.file(),
513510
inputFileOrErr.getError().message());
514-
return std::make_pair(nullptr, nullptr);
511+
return {nullptr, nullptr, nullptr};
515512
}
516513
if (!serialization::isSerializedAST((*inputFileOrErr)->getBuffer()))
517-
return std::make_pair(std::move(*inputFileOrErr), nullptr);
514+
return {std::move(*inputFileOrErr), nullptr, nullptr};
518515

519-
if (Optional<std::unique_ptr<llvm::MemoryBuffer>> moduleDocBuffer =
520-
openModuleDoc(input)) {
521-
return std::make_pair(std::move(*inputFileOrErr),
522-
std::move(*moduleDocBuffer));
523-
}
524-
return std::make_pair(nullptr, nullptr);
516+
Optional<std::unique_ptr<llvm::MemoryBuffer>> moduleDocBuffer = openModuleDoc(input);
517+
Optional<std::unique_ptr<llvm::MemoryBuffer>> moduleSourceInfoBuffer = openModuleSourceInfo(input);
518+
519+
return {
520+
std::move(*inputFileOrErr),
521+
moduleDocBuffer.hasValue() ? std::move(*moduleDocBuffer): nullptr,
522+
moduleSourceInfoBuffer.hasValue() ? std::move(*moduleSourceInfoBuffer): nullptr
523+
};
524+
}
525+
526+
Optional<std::unique_ptr<llvm::MemoryBuffer>>
527+
CompilerInstance::openModuleSourceInfo(const InputFile &input) {
528+
llvm::SmallString<128> moduleSourceInfoFilePath(input.file());
529+
llvm::sys::path::replace_extension(moduleSourceInfoFilePath,
530+
file_types::getExtension(file_types::TY_SwiftSourceInfoFile));
531+
std::string NonPrivatePath = moduleSourceInfoFilePath.str().str();
532+
StringRef fileName = llvm::sys::path::filename(NonPrivatePath);
533+
llvm::sys::path::remove_filename(moduleSourceInfoFilePath);
534+
llvm::sys::path::append(moduleSourceInfoFilePath, "Private");
535+
llvm::sys::path::append(moduleSourceInfoFilePath, fileName);
536+
if (auto sourceInfoFileOrErr = swift::vfs::getFileOrSTDIN(getFileSystem(),
537+
moduleSourceInfoFilePath))
538+
return std::move(*sourceInfoFileOrErr);
539+
if (auto sourceInfoFileOrErr = swift::vfs::getFileOrSTDIN(getFileSystem(), NonPrivatePath))
540+
return std::move(*sourceInfoFileOrErr);
541+
return None;
525542
}
526543

527544
Optional<std::unique_ptr<llvm::MemoryBuffer>>
@@ -898,7 +915,8 @@ bool CompilerInstance::parsePartialModulesAndLibraryFiles(
898915
for (auto &PM : PartialModules) {
899916
assert(PM.ModuleBuffer);
900917
if (!SML->loadAST(*MainModule, SourceLoc(), std::move(PM.ModuleBuffer),
901-
std::move(PM.ModuleDocBuffer), /*isFramework*/false,
918+
std::move(PM.ModuleDocBuffer),
919+
std::move(PM.ModuleSourceInfoBuffer), /*isFramework*/false,
902920
/*treatAsPartialModule*/true))
903921
hadLoadError = true;
904922
}

lib/Frontend/ModuleInterfaceLoader.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -986,8 +986,10 @@ bool ModuleInterfaceLoader::isCached(StringRef DepPath) {
986986
std::error_code ModuleInterfaceLoader::findModuleFilesInDirectory(
987987
AccessPathElem ModuleID, StringRef DirPath, StringRef ModuleFilename,
988988
StringRef ModuleDocFilename,
989+
StringRef ModuleSourceInfoFilename,
989990
std::unique_ptr<llvm::MemoryBuffer> *ModuleBuffer,
990-
std::unique_ptr<llvm::MemoryBuffer> *ModuleDocBuffer) {
991+
std::unique_ptr<llvm::MemoryBuffer> *ModuleDocBuffer,
992+
std::unique_ptr<llvm::MemoryBuffer> *ModuleSourceInfoBuffer) {
991993

992994
// If running in OnlySerialized mode, ModuleInterfaceLoader
993995
// should not have been constructed at all.

0 commit comments

Comments
 (0)