Skip to content

Commit e6f7b9d

Browse files
authored
Merge pull request swiftlang#33926 from CodaFi/just-my-kind
[NFC] Refactor InputFile
2 parents 1298f71 + f9e0294 commit e6f7b9d

25 files changed

+252
-258
lines changed

include/swift/AST/Module.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -458,7 +458,7 @@ class ModuleDecl : public DeclContext, public TypeDecl {
458458

459459
/// Convenience accessor for clients that know what kind of file they're
460460
/// dealing with.
461-
SourceFile &getMainSourceFile(SourceFileKind expectedKind) const;
461+
SourceFile &getMainSourceFile() const;
462462

463463
/// Convenience accessor for clients that know what kind of file they're
464464
/// dealing with.

include/swift/AST/SourceFile.h

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -624,10 +624,8 @@ inline SourceFile::ParsingOptions operator|(SourceFile::ParsingFlags lhs,
624624
return SourceFile::ParsingOptions(lhs) | rhs;
625625
}
626626

627-
inline SourceFile &
628-
ModuleDecl::getMainSourceFile(SourceFileKind expectedKind) const {
627+
inline SourceFile &ModuleDecl::getMainSourceFile() const {
629628
assert(!Files.empty() && "No files added yet");
630-
assert(cast<SourceFile>(Files.front())->Kind == expectedKind);
631629
return *cast<SourceFile>(Files.front());
632630
}
633631

include/swift/Frontend/Frontend.h

Lines changed: 4 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -287,16 +287,6 @@ class CompilerInvocation {
287287
return FrontendOpts.ParseStdlib;
288288
}
289289

290-
void setInputKind(InputFileKind K) {
291-
FrontendOpts.InputKind = K;
292-
}
293-
294-
InputFileKind getInputKind() const {
295-
return FrontendOpts.InputKind;
296-
}
297-
298-
SourceFileKind getSourceFileKind() const;
299-
300290
void setModuleName(StringRef Name) {
301291
FrontendOpts.ModuleName = Name.str();
302292
IRGenOpts.ModuleName = Name.str();
@@ -335,7 +325,7 @@ class CompilerInvocation {
335325

336326
/// Retrieve the stdlib kind to implicitly import.
337327
ImplicitStdlibKind getImplicitStdlibKind() const {
338-
if (getInputKind() == InputFileKind::SIL) {
328+
if (FrontendOpts.InputMode == FrontendOptions::ParseInputMode::SIL) {
339329
return ImplicitStdlibKind::None;
340330
}
341331
if (getParseStdlib()) {
@@ -354,9 +344,6 @@ class CompilerInvocation {
354344
setUpInputForSILTool(StringRef inputFilename, StringRef moduleNameArg,
355345
bool alwaysSetModuleToMain, bool bePrimary,
356346
serialization::ExtendedValidationInfo &extendedInfo);
357-
bool hasSerializedAST() {
358-
return FrontendOpts.InputKind == InputFileKind::SwiftLibrary;
359-
}
360347

361348
const PrimarySpecificPaths &
362349
getPrimarySpecificPathsForAtMostOnePrimary() const;
@@ -443,9 +430,6 @@ class CompilerInstance {
443430
/// \c mutable as it is consumed by \c loadPartialModulesAndImplicitImports.
444431
mutable std::vector<ModuleBuffers> PartialModules;
445432

446-
enum : unsigned { NO_SUCH_BUFFER = ~0U };
447-
unsigned MainBufferID = NO_SUCH_BUFFER;
448-
449433
/// Identifies the set of input buffers in the SourceManager that are
450434
/// considered primaries.
451435
llvm::SetVector<unsigned> PrimaryBufferIDs;
@@ -565,24 +549,13 @@ class CompilerInstance {
565549
void setUpLLVMArguments();
566550
void setUpDiagnosticOptions();
567551
bool setUpModuleLoaders();
568-
bool isInputSwift() {
569-
return Invocation.getInputKind() == InputFileKind::Swift;
570-
}
571-
bool isInSILMode() {
572-
return Invocation.getInputKind() == InputFileKind::SIL;
573-
}
574-
575552
bool setUpInputs();
576553
bool setUpASTContextIfNeeded();
577554
void setupStatsReporter();
578555
void setupDiagnosticVerifierIfNeeded();
579556
void setupDependencyTrackerIfNeeded();
580557
Optional<unsigned> setUpCodeCompletionBuffer();
581558

582-
/// Set up all state in the CompilerInstance to process the given input file.
583-
/// Return true on error.
584-
bool setUpForInput(const InputFile &input);
585-
586559
/// Find a buffer for a given input file and ensure it is recorded in
587560
/// SourceMgr, PartialModules, or InputSourceCodeBufferIDs as appropriate.
588561
/// Return the buffer ID if it is not already compiled, or None if so.
@@ -626,12 +599,14 @@ class CompilerInstance {
626599
/// Creates a new source file for the main module.
627600
SourceFile *createSourceFileForMainModule(ModuleDecl *mod,
628601
SourceFileKind FileKind,
629-
Optional<unsigned> BufferID) const;
602+
Optional<unsigned> BufferID,
603+
bool isMainBuffer = false) const;
630604

631605
/// Creates all the files to be added to the main module, appending them to
632606
/// \p files. If a loading error occurs, returns \c true.
633607
bool createFilesForMainModule(ModuleDecl *mod,
634608
SmallVectorImpl<FileUnit *> &files) const;
609+
SourceFile *computeMainSourceFileForModule(ModuleDecl *mod) const;
635610

636611
public:
637612
void freeASTContext();

include/swift/Frontend/FrontendOptions.h

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -39,9 +39,6 @@ class FrontendOptions {
3939
public:
4040
FrontendInputsAndOutputs InputsAndOutputs;
4141

42-
/// The kind of input on which the frontend should operate.
43-
InputFileKind InputKind = InputFileKind::Swift;
44-
4542
void forAllOutputPaths(const InputFile &input,
4643
llvm::function_ref<void(StringRef)> fn) const;
4744

@@ -143,6 +140,14 @@ class FrontendOptions {
143140
/// Indicates the action the user requested that the frontend perform.
144141
ActionType RequestedAction = ActionType::NoneAction;
145142

143+
enum class ParseInputMode {
144+
Swift,
145+
SwiftLibrary,
146+
SwiftModuleInterface,
147+
SIL,
148+
};
149+
ParseInputMode InputMode = ParseInputMode::Swift;
150+
146151
/// Indicates that the input(s) should be parsed as the Swift stdlib.
147152
bool ParseStdlib = false;
148153

@@ -316,8 +321,8 @@ class FrontendOptions {
316321
StringRef determineFallbackModuleName() const;
317322

318323
bool isCompilingExactlyOneSwiftFile() const {
319-
return InputKind == InputFileKind::Swift &&
320-
InputsAndOutputs.hasSingleInput();
324+
return InputsAndOutputs.hasSingleInput() &&
325+
InputMode == ParseInputMode::Swift;
321326
}
322327

323328
const PrimarySpecificPaths &

include/swift/Frontend/InputFile.h

Lines changed: 69 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -13,54 +13,80 @@
1313
#ifndef SWIFT_FRONTEND_INPUTFILE_H
1414
#define SWIFT_FRONTEND_INPUTFILE_H
1515

16+
#include "swift/Basic/FileTypes.h"
1617
#include "swift/Basic/PrimarySpecificPaths.h"
1718
#include "swift/Basic/SupplementaryOutputPaths.h"
19+
#include "llvm/ADT/PointerIntPair.h"
1820
#include "llvm/Support/MemoryBuffer.h"
21+
#include "llvm/Support/Path.h"
1922
#include <string>
2023

2124
namespace swift {
2225

23-
enum class InputFileKind {
24-
None,
25-
Swift,
26-
SwiftLibrary,
27-
SwiftModuleInterface,
28-
SIL,
29-
LLVM,
30-
ObjCHeader,
31-
};
32-
33-
// Inputs may include buffers that override contents, and eventually should
34-
// always include a buffer.
35-
class InputFile {
26+
/// An \c InputFile encapsulates information about an input passed to the
27+
/// frontend.
28+
///
29+
/// Compiler inputs are usually passed on the command line without a leading
30+
/// flag. However, there are clients that use the \c CompilerInvocation as
31+
/// a library like LLDB and SourceKit that generate their own \c InputFile
32+
/// instances programmatically. Note that an \c InputFile need not actually be
33+
/// backed by a physical file, nor does its file name actually reflect its
34+
/// contents. \c InputFile has a constructor that will try to figure out the file
35+
/// type from the file name if none is provided, but many clients that
36+
/// construct \c InputFile instances themselves may provide bogus file names
37+
/// with pre-computed kinds. It is imperative that \c InputFile::getType be used
38+
/// as a source of truth for this information.
39+
///
40+
/// \warning \c InputFile takes an unfortunately lax view of the ownership of
41+
/// its primary data. It currently only owns the file name and a copy of any
42+
/// assigned \c PrimarySpecificPaths outright. It is the responsibility of the
43+
/// caller to ensure that an associated memory buffer outlives the \c InputFile.
44+
class InputFile final {
3645
std::string Filename;
37-
bool IsPrimary;
38-
/// Points to a buffer overriding the file's contents, or nullptr if there is
39-
/// none.
40-
llvm::MemoryBuffer *Buffer;
41-
42-
/// If there are explicit primary inputs (i.e. designated with -primary-input
43-
/// or -primary-filelist), the paths specific to those inputs (other than the
44-
/// input file path itself) are kept here. If there are no explicit primary
45-
/// inputs (for instance for whole module optimization), the corresponding
46-
/// paths are kept in the first input file.
46+
file_types::ID FileID;
47+
llvm::PointerIntPair<llvm::MemoryBuffer *, 1, bool> BufferAndIsPrimary;
4748
PrimarySpecificPaths PSPs;
4849

4950
public:
50-
/// Does not take ownership of \p buffer. Does take ownership of (copy) a
51-
/// string.
51+
/// Constructs an input file from the provided data.
52+
///
53+
/// \warning This entrypoint infers the type of the file from its extension
54+
/// and is therefore not suitable for most clients that use files synthesized
55+
/// from memory buffers. Use the overload of this constructor accepting a
56+
/// memory buffer and an explicit \c file_types::ID instead.
5257
InputFile(StringRef name, bool isPrimary,
53-
llvm::MemoryBuffer *buffer = nullptr,
54-
StringRef outputFilename = StringRef())
58+
llvm::MemoryBuffer *buffer = nullptr)
59+
: InputFile(name, isPrimary, buffer,
60+
file_types::lookupTypeForExtension(
61+
llvm::sys::path::extension(name))) {}
62+
63+
/// Constructs an input file from the provided data.
64+
InputFile(StringRef name, bool isPrimary, llvm::MemoryBuffer *buffer,
65+
file_types::ID FileID)
5566
: Filename(
5667
convertBufferNameFromLLVM_getFileOrSTDIN_toSwiftConventions(name)),
57-
IsPrimary(isPrimary), Buffer(buffer), PSPs(PrimarySpecificPaths()) {
68+
FileID(FileID), BufferAndIsPrimary(buffer, isPrimary),
69+
PSPs(PrimarySpecificPaths()) {
5870
assert(!name.empty());
5971
}
6072

61-
bool isPrimary() const { return IsPrimary; }
62-
llvm::MemoryBuffer *buffer() const { return Buffer; }
63-
const std::string &file() const {
73+
public:
74+
/// Retrieves the type of this input file.
75+
file_types::ID getType() const { return FileID; };
76+
77+
/// Retrieves whether this input file was passed as a primary to the frontend.
78+
bool isPrimary() const { return BufferAndIsPrimary.getInt(); }
79+
80+
/// Retrieves the backing buffer for this input file, if any.
81+
llvm::MemoryBuffer *getBuffer() const {
82+
return BufferAndIsPrimary.getPointer();
83+
}
84+
85+
/// The name of this \c InputFile, or `-` if this input corresponds to the
86+
/// standard input stream.
87+
///
88+
/// The returned file name is guaranteed not to be the empty string.
89+
const std::string &getFileName() const {
6490
assert(!Filename.empty());
6591
return Filename;
6692
}
@@ -72,12 +98,22 @@ class InputFile {
7298
return filename.equals("<stdin>") ? "-" : filename;
7399
}
74100

101+
/// Retrieves the name of the output file corresponding to this input.
102+
///
103+
/// If there is no such corresponding file, the result is the empty string.
104+
/// If there the resulting output should be directed to the standard output
105+
/// stream, the result is "-".
75106
std::string outputFilename() const { return PSPs.OutputFilename; }
76107

108+
/// If there are explicit primary inputs (i.e. designated with -primary-input
109+
/// or -primary-filelist), the paths specific to those inputs (other than the
110+
/// input file path itself) are kept here. If there are no explicit primary
111+
/// inputs (for instance for whole module optimization), the corresponding
112+
/// paths are kept in the first input file.
77113
const PrimarySpecificPaths &getPrimarySpecificPaths() const { return PSPs; }
78114

79-
void setPrimarySpecificPaths(const PrimarySpecificPaths &PSPs) {
80-
this->PSPs = PSPs;
115+
void setPrimarySpecificPaths(PrimarySpecificPaths &&PSPs) {
116+
this->PSPs = std::move(PSPs);
81117
}
82118

83119
// The next set of functions provides access to those primary-specific paths

lib/Frontend/ArgsToFrontendOptionsConverter.cpp

Lines changed: 12 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -143,6 +143,16 @@ bool ArgsToFrontendOptionsConverter::convert(
143143
Opts.InputsAndOutputs = std::move(inputsAndOutputs).getValue();
144144
}
145145

146+
if (Args.hasArg(OPT_parse_sil) || Opts.InputsAndOutputs.shouldTreatAsSIL()) {
147+
Opts.InputMode = FrontendOptions::ParseInputMode::SIL;
148+
} else if (Opts.InputsAndOutputs.shouldTreatAsModuleInterface()) {
149+
Opts.InputMode = FrontendOptions::ParseInputMode::SwiftModuleInterface;
150+
} else if (Args.hasArg(OPT_parse_as_library)) {
151+
Opts.InputMode = FrontendOptions::ParseInputMode::SwiftLibrary;
152+
} else {
153+
Opts.InputMode = FrontendOptions::ParseInputMode::Swift;
154+
}
155+
146156
if (Opts.RequestedAction == FrontendOptions::ActionType::NoneAction) {
147157
Opts.RequestedAction = determineRequestedAction(Args);
148158
}
@@ -163,7 +173,7 @@ bool ArgsToFrontendOptionsConverter::convert(
163173
return true;
164174
}
165175

166-
if (setUpInputKindAndImmediateArgs())
176+
if (setUpImmediateArgs())
167177
return true;
168178

169179
if (computeModuleName())
@@ -398,7 +408,7 @@ ArgsToFrontendOptionsConverter::determineRequestedAction(const ArgList &args) {
398408
llvm_unreachable("Unhandled mode option");
399409
}
400410

401-
bool ArgsToFrontendOptionsConverter::setUpInputKindAndImmediateArgs() {
411+
bool ArgsToFrontendOptionsConverter::setUpImmediateArgs() {
402412
using namespace options;
403413
bool treatAsSIL =
404414
Args.hasArg(OPT_parse_sil) || Opts.InputsAndOutputs.shouldTreatAsSIL();
@@ -419,19 +429,6 @@ bool ArgsToFrontendOptionsConverter::setUpInputKindAndImmediateArgs() {
419429
}
420430
}
421431

422-
if (treatAsSIL)
423-
Opts.InputKind = InputFileKind::SIL;
424-
else if (Opts.InputsAndOutputs.shouldTreatAsLLVM())
425-
Opts.InputKind = InputFileKind::LLVM;
426-
else if (Opts.InputsAndOutputs.shouldTreatAsObjCHeader())
427-
Opts.InputKind = InputFileKind::ObjCHeader;
428-
else if (Opts.InputsAndOutputs.shouldTreatAsModuleInterface())
429-
Opts.InputKind = InputFileKind::SwiftModuleInterface;
430-
else if (Args.hasArg(OPT_parse_as_library))
431-
Opts.InputKind = InputFileKind::SwiftLibrary;
432-
else
433-
Opts.InputKind = InputFileKind::Swift;
434-
435432
return false;
436433
}
437434

lib/Frontend/ArgsToFrontendOptionsConverter.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ class ArgsToFrontendOptionsConverter {
4747
void computePrintStatsOptions();
4848
void computeTBDOptions();
4949

50-
bool setUpInputKindAndImmediateArgs();
50+
bool setUpImmediateArgs();
5151

5252
bool checkUnusedSupplementaryOutputPaths() const;
5353

lib/Frontend/ArgsToFrontendOutputsConverter.cpp

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -183,7 +183,7 @@ OutputFilesComputer::computeOutputFile(StringRef outputArg,
183183

184184
Optional<std::string>
185185
OutputFilesComputer::deriveOutputFileFromInput(const InputFile &input) const {
186-
if (input.file() == "-" || HasTextualOutput)
186+
if (input.getFileName() == "-" || HasTextualOutput)
187187
return std::string("-");
188188

189189
std::string baseName = determineBaseNameOfOutput(input);
@@ -210,7 +210,7 @@ std::string
210210
OutputFilesComputer::determineBaseNameOfOutput(const InputFile &input) const {
211211
std::string nameToStem =
212212
input.isPrimary()
213-
? input.file()
213+
? input.getFileName()
214214
: ModuleNameArg ? ModuleNameArg->getValue() : FirstInput;
215215
return llvm::sys::path::stem(nameToStem).str();
216216
}
@@ -474,8 +474,8 @@ StringRef SupplementaryOutputPathsComputer::
474474
if (!outputFilename.empty() && outputFilename != "-")
475475
return outputFilename;
476476

477-
if (input.isPrimary() && input.file() != "-")
478-
return llvm::sys::path::filename(input.file());
477+
if (input.isPrimary() && input.getFileName() != "-")
478+
return llvm::sys::path::filename(input.getFileName());
479479

480480
return ModuleName;
481481
}
@@ -600,12 +600,12 @@ SupplementaryOutputPathsComputer::readSupplementaryOutputFileMap() const {
600600
InputsAndOutputs.forEachInputProducingSupplementaryOutput(
601601
[&](const InputFile &input) -> bool {
602602
const TypeToPathMap *mapForInput =
603-
OFM->getOutputMapForInput(input.file());
603+
OFM->getOutputMapForInput(input.getFileName());
604604
if (!mapForInput) {
605605
Diags.diagnose(
606606
SourceLoc(),
607607
diag::error_missing_entry_in_supplementary_output_file_map,
608-
supplementaryFileMapPath, input.file());
608+
supplementaryFileMapPath, input.getFileName());
609609
hadError = true;
610610
}
611611
outputPaths.push_back(createFromTypeToPathMap(mapForInput));

0 commit comments

Comments
 (0)