Skip to content

Commit 82d4386

Browse files
author
David Ungar
authored
Merge pull request #13982 from davidungar/PR-18-3
Preparing CompilerInstance for batch mode.
2 parents 4953262 + df02341 commit 82d4386

File tree

4 files changed

+198
-85
lines changed

4 files changed

+198
-85
lines changed

include/swift/Frontend/Frontend.h

Lines changed: 53 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@
3939
#include "swift/Serialization/Validation.h"
4040
#include "swift/Subsystems.h"
4141
#include "llvm/ADT/IntrusiveRefCntPtr.h"
42+
#include "llvm/ADT/SetVector.h"
4243
#include "llvm/Option/ArgList.h"
4344
#include "llvm/Support/Host.h"
4445
#include "llvm/Support/MemoryBuffer.h"
@@ -336,14 +337,31 @@ class CompilerInstance {
336337
enum : unsigned { NO_SUCH_BUFFER = ~0U };
337338
unsigned MainBufferID = NO_SUCH_BUFFER;
338339

339-
/// PrimaryBufferID corresponds to PrimaryInput.
340-
unsigned PrimaryBufferID = NO_SUCH_BUFFER;
341-
bool isWholeModuleCompilation() { return PrimaryBufferID == NO_SUCH_BUFFER; }
340+
/// Identifies the set of input buffers in the SourceManager that are
341+
/// considered primaries.
342+
llvm::SetVector<unsigned> PrimaryBufferIDs;
342343

343-
SourceFile *PrimarySourceFile = nullptr;
344+
/// Identifies the set of SourceFiles that are considered primaries. An
345+
/// invariant is that any SourceFile in this set with an associated
346+
/// buffer will also have its buffer ID in PrimaryBufferIDs.
347+
std::vector<SourceFile *> PrimarySourceFiles;
348+
349+
/// Return whether there is an entry in PrimaryInputs for buffer \p BufID.
350+
bool isPrimaryInput(unsigned BufID) const {
351+
return PrimaryBufferIDs.count(BufID) != 0;
352+
}
353+
354+
/// Record in PrimaryBufferIDs the fact that \p BufID is a primary.
355+
/// If \p BufID is already in the set, do nothing.
356+
void recordPrimaryInputBuffer(unsigned BufID);
357+
358+
/// Record in PrimarySourceFiles the fact that \p SF is a primary, and
359+
/// call recordPrimaryInputBuffer on \p SF's buffer (if it exists).
360+
void recordPrimarySourceFile(SourceFile *SF);
361+
362+
bool isWholeModuleCompilation() { return PrimaryBufferIDs.empty(); }
344363

345364
void createSILModule();
346-
void setPrimarySourceFile(SourceFile *SF);
347365

348366
public:
349367
SourceManager &getSourceMgr() { return SourceMgr; }
@@ -371,7 +389,7 @@ class CompilerInstance {
371389
}
372390

373391
void setReferencedNameTracker(ReferencedNameTracker *tracker) {
374-
assert(!PrimarySourceFile && "must be called before performSema()");
392+
assert(PrimarySourceFiles.empty() && "must be called before performSema()");
375393
NameTracker = tracker;
376394
}
377395
ReferencedNameTracker *getReferencedNameTracker() {
@@ -413,9 +431,36 @@ class CompilerInstance {
413431
return Invocation.getFrontendOptions().EnableSourceImport;
414432
}
415433

434+
/// Gets the set of SourceFiles which are the primary inputs for this
435+
/// CompilerInstance.
436+
ArrayRef<SourceFile *> getPrimarySourceFiles() {
437+
return PrimarySourceFiles;
438+
}
439+
440+
/// Gets the Primary Source File if one exists, otherwise the main
441+
/// module. If multiple Primary Source Files exist, fails with an
442+
/// assertion.
443+
ModuleOrSourceFile getPrimarySourceFileOrMainModule() {
444+
if (PrimarySourceFiles.empty())
445+
return getMainModule();
446+
else
447+
return getPrimarySourceFile();
448+
}
449+
416450
/// Gets the SourceFile which is the primary input for this CompilerInstance.
417-
/// \returns the primary SourceFile, or nullptr if there is no primary input
418-
SourceFile *getPrimarySourceFile() { return PrimarySourceFile; }
451+
/// \returns the primary SourceFile, or nullptr if there is no primary input;
452+
/// if there are _multiple_ primary inputs, fails with an assertion.
453+
///
454+
/// FIXME: This should be removed eventually, once there are no longer any
455+
/// codepaths that rely on a single primary file.
456+
SourceFile *getPrimarySourceFile() {
457+
if (PrimarySourceFiles.empty()) {
458+
return nullptr;
459+
} else {
460+
assert(PrimarySourceFiles.size() == 1);
461+
return *PrimarySourceFiles.begin();
462+
}
463+
}
419464

420465
/// \brief Returns true if there was an error during setup.
421466
bool setup(const CompilerInvocation &Invocation);

lib/Frontend/Frontend.cpp

Lines changed: 25 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -61,14 +61,16 @@ void CompilerInstance::createSILModule() {
6161
Invocation.getFrontendOptions().Inputs.isWholeModule());
6262
}
6363

64-
void CompilerInstance::setPrimarySourceFile(SourceFile *SF) {
65-
assert(SF);
64+
void CompilerInstance::recordPrimaryInputBuffer(unsigned BufID) {
65+
PrimaryBufferIDs.insert(BufID);
66+
}
67+
68+
void CompilerInstance::recordPrimarySourceFile(SourceFile *SF) {
6669
assert(MainModule && "main module not created yet");
67-
assert(!PrimarySourceFile && "already has a primary source file");
68-
assert(PrimaryBufferID == NO_SUCH_BUFFER || !SF->getBufferID().hasValue() ||
69-
SF->getBufferID().getValue() == PrimaryBufferID);
70-
PrimarySourceFile = SF;
71-
PrimarySourceFile->setReferencedNameTracker(NameTracker);
70+
PrimarySourceFiles.push_back(SF);
71+
SF->setReferencedNameTracker(NameTracker);
72+
if (SF->getBufferID().hasValue())
73+
recordPrimaryInputBuffer(SF->getBufferID().getValue());
7274
}
7375

7476
bool CompilerInstance::setup(const CompilerInvocation &Invok) {
@@ -186,9 +188,9 @@ bool CompilerInstance::setUpInputs() {
186188

187189
// Set the primary file to the code-completion point if one exists.
188190
if (codeCompletionBufferID.hasValue() &&
189-
*codeCompletionBufferID != PrimaryBufferID) {
190-
assert(PrimaryBufferID == NO_SUCH_BUFFER && "re-setting PrimaryBufferID");
191-
PrimaryBufferID = *codeCompletionBufferID;
191+
!isPrimaryInput(*codeCompletionBufferID)) {
192+
assert(PrimaryBufferIDs.empty() && "re-setting PrimaryBufferID");
193+
recordPrimaryInputBuffer(*codeCompletionBufferID);
192194
}
193195

194196
if (isInputSwift() && MainBufferID == NO_SUCH_BUFFER &&
@@ -214,8 +216,8 @@ bool CompilerInstance::setUpForInput(const InputFile &input) {
214216
}
215217

216218
if (input.isPrimary()) {
217-
assert(PrimaryBufferID == NO_SUCH_BUFFER && "re-setting PrimaryBufferID");
218-
PrimaryBufferID = *bufferID;
219+
assert(PrimaryBufferIDs.empty() && "re-setting PrimaryBufferID");
220+
recordPrimaryInputBuffer(*bufferID);
219221
}
220222
return false;
221223
}
@@ -587,15 +589,15 @@ void CompilerInstance::parseLibraryFile(
587589
addAdditionalInitialImportsTo(NextInput, implicitImports);
588590

589591
auto *DelayedCB = SecondaryDelayedCB;
590-
if (BufferID == PrimaryBufferID) {
592+
if (isPrimaryInput(BufferID)) {
591593
DelayedCB = PrimaryDelayedCB;
592594
}
593595
if (isWholeModuleCompilation())
594596
DelayedCB = PrimaryDelayedCB;
595597

596598
auto &Diags = NextInput->getASTContext().Diags;
597599
auto DidSuppressWarnings = Diags.getSuppressWarnings();
598-
auto IsPrimary = isWholeModuleCompilation() || BufferID == PrimaryBufferID;
600+
auto IsPrimary = isWholeModuleCompilation() || isPrimaryInput(BufferID);
599601
Diags.setSuppressWarnings(DidSuppressWarnings || !IsPrimary);
600602

601603
bool Done;
@@ -661,7 +663,7 @@ void CompilerInstance::parseAndTypeCheckMainFile(
661663
SharedTimer timer(
662664
"performSema-checkTypesWhileParsingMain-parseAndTypeCheckMainFile");
663665
bool mainIsPrimary =
664-
(isWholeModuleCompilation() || MainBufferID == PrimaryBufferID);
666+
(isWholeModuleCompilation() || isPrimaryInput(MainBufferID));
665667

666668
SourceFile &MainFile =
667669
MainModule->getMainSourceFile(Invocation.getSourceFileKind());
@@ -724,7 +726,9 @@ void CompilerInstance::forEachFileToTypeCheck(
724726
if (isWholeModuleCompilation()) {
725727
forEachSourceFileIn(MainModule, [&](SourceFile &SF) { fn(SF); });
726728
} else {
727-
fn(*PrimarySourceFile);
729+
for (auto *SF : PrimarySourceFiles) {
730+
fn(*SF);
731+
}
728732
}
729733
}
730734

@@ -746,8 +750,9 @@ SourceFile *CompilerInstance::createSourceFileForMainModule(
746750
SourceFile(*mainModule, fileKind, bufferID, importKind, keepSyntaxInfo);
747751
MainModule->addFile(*inputFile);
748752

749-
if (bufferID && *bufferID == PrimaryBufferID)
750-
setPrimarySourceFile(inputFile);
753+
if (bufferID && isPrimaryInput(*bufferID)) {
754+
recordPrimarySourceFile(inputFile);
755+
}
751756

752757
return inputFile;
753758
}
@@ -813,6 +818,7 @@ void CompilerInstance::freeContextAndSIL() {
813818
TheSILModule.reset();
814819
MainModule = nullptr;
815820
SML = nullptr;
816-
PrimarySourceFile = nullptr;
821+
PrimaryBufferIDs.clear();
822+
PrimarySourceFiles.clear();
817823
}
818824

0 commit comments

Comments
 (0)