diff --git a/include/swift/Frontend/FrontendInputsAndOutputs.h b/include/swift/Frontend/FrontendInputsAndOutputs.h index 42211e96c59..4205b1965a1 100644 --- a/include/swift/Frontend/FrontendInputsAndOutputs.h +++ b/include/swift/Frontend/FrontendInputsAndOutputs.h @@ -33,8 +33,8 @@ class FrontendInputsAndOutputs { friend class ArgsToFrontendInputsConverter; std::vector AllInputs; - typedef llvm::StringMap InputFileMap; - InputFileMap PrimaryInputs; + + llvm::StringMap PrimaryInputs; public: FrontendInputsAndOutputs() = default; @@ -43,6 +43,8 @@ public: // Readers: + // All inputs: + ArrayRef getAllInputs() const { return AllInputs; } std::vector getInputFilenames() const; @@ -53,22 +55,25 @@ public: bool hasSingleInput() const { return inputCount() == 1; } + const InputFile &firstInput() const { return AllInputs[0]; } + InputFile &firstInput() { return AllInputs[0]; } + + const InputFile &lastInput() const { return AllInputs.back(); } + StringRef getFilenameOfFirstInput() const; bool isReadingFromStdin() const; - // If we have exactly one input filename, and its extension is "bc" or "ll", - // treat the input as LLVM_IR. - bool shouldTreatAsLLVM() const; + void forEachInput(llvm::function_ref fn) const; - // Primary input readers + // Primaries: -private: - void assertMustNotBeMoreThanOnePrimaryInput() const; + const InputFile &firstPrimaryInput() const; + const InputFile &lastPrimaryInput() const; - bool areAllNonPrimariesSIB() const; + void + forEachPrimaryInput(llvm::function_ref fn) const; -public: unsigned primaryInputCount() const { return PrimaryInputs.size(); } // Primary count readers: @@ -79,6 +84,11 @@ public: bool isWholeModule() const { return !hasPrimaryInputs(); } + /// Fails an assertion if there is more than one primary input. + /// Used in situations where only one primary input can be handled + /// and where batch mode has not been implemented yet. + void assertMustNotBeMoreThanOnePrimaryInput() const; + // Count-dependend readers: /// \return the unique primary input, if one exists. @@ -96,28 +106,25 @@ public: // Multi-facet readers + // If we have exactly one input filename, and its extension is "bc" or "ll", + // treat the input as LLVM_IR. + bool shouldTreatAsLLVM() const; bool shouldTreatAsSIL() const; + bool areAllNonPrimariesSIB() const; + /// \return true for error bool verifyInputs(DiagnosticEngine &diags, bool treatAsSIL, bool isREPLRequested, bool isNoneRequested) const; - // Writers - - void addInputFile(StringRef file, llvm::MemoryBuffer *buffer = nullptr) { - addInput(InputFile(file, false, buffer)); - } - void addPrimaryInputFile(StringRef file, - llvm::MemoryBuffer *buffer = nullptr) { - addInput(InputFile(file, true, buffer)); - } + // Changing inputs +public: + void clearInputs(); void addInput(const InputFile &input); - - void clearInputs() { - AllInputs.clear(); - PrimaryInputs.clear(); - } + void addInputFile(StringRef file, llvm::MemoryBuffer *buffer = nullptr); + void addPrimaryInputFile(StringRef file, + llvm::MemoryBuffer *buffer = nullptr); }; } // namespace swift diff --git a/lib/Frontend/FrontendInputsAndOutputs.cpp b/lib/Frontend/FrontendInputsAndOutputs.cpp index e2c2ab34046..f4229f4e0b6 100644 --- a/lib/Frontend/FrontendInputsAndOutputs.cpp +++ b/lib/Frontend/FrontendInputsAndOutputs.cpp @@ -58,6 +58,45 @@ bool FrontendInputsAndOutputs::isReadingFromStdin() const { return hasSingleInput() && getFilenameOfFirstInput() == "-"; } +StringRef FrontendInputsAndOutputs::getFilenameOfFirstInput() const { + assert(hasInputs()); + const InputFile &inp = AllInputs[0]; + StringRef f = inp.file(); + assert(!f.empty()); + return f; +} + +void FrontendInputsAndOutputs::forEachInput( + llvm::function_ref fn) const { + for (const InputFile &input : AllInputs) + fn(input); +} + +// Primaries: + +const InputFile &FrontendInputsAndOutputs::firstPrimaryInput() const { + assert(!PrimaryInputs.empty()); + for (const auto &f : AllInputs) + if (f.isPrimary()) + return f; + llvm_unreachable("no first primary?!"); +} + +const InputFile &FrontendInputsAndOutputs::lastPrimaryInput() const { + assert(!PrimaryInputs.empty()); + for (const auto &f : reversed(AllInputs)) + if (f.isPrimary()) + return f; + llvm_unreachable("no last primary?!"); +} + +void FrontendInputsAndOutputs::forEachPrimaryInput( + llvm::function_ref fn) const { + for (auto &f : AllInputs) + if (f.isPrimary()) + fn(f); +} + void FrontendInputsAndOutputs::assertMustNotBeMoreThanOnePrimaryInput() const { assert(primaryInputCount() < 2 && "have not implemented >1 primary input yet"); @@ -87,14 +126,18 @@ bool FrontendInputsAndOutputs::isInputPrimary(StringRef file) const { AllInputs[iterator->second].isPrimary(); } -StringRef FrontendInputsAndOutputs::getFilenameOfFirstInput() const { - assert(hasInputs()); - const InputFile &inp = AllInputs[0]; - StringRef f = inp.file(); - assert(!f.empty()); - return f; +unsigned FrontendInputsAndOutputs::numberOfPrimaryInputsEndingWith( + const char *extension) const { + return count_if( + PrimaryInputs, [&](const llvm::StringMapEntry &elem) -> bool { + StringRef filename = AllInputs[elem.second].file(); + + return llvm::sys::path::extension(filename).endswith(extension); + }); } +// Input queries + bool FrontendInputsAndOutputs::shouldTreatAsLLVM() const { if (hasSingleInput()) { StringRef Input(getFilenameOfFirstInput()); @@ -124,19 +167,15 @@ bool FrontendInputsAndOutputs::shouldTreatAsSIL() const { llvm_unreachable("Either all primaries or none must end with .sil"); } -void FrontendInputsAndOutputs::addInput(const InputFile &input) { - if (!input.file().empty() && input.isPrimary()) - PrimaryInputs.insert(std::make_pair(input.file(), AllInputs.size())); - AllInputs.push_back(input); -} - -unsigned FrontendInputsAndOutputs::numberOfPrimaryInputsEndingWith( - const char *extension) const { - return count_if( - PrimaryInputs, [&](const llvm::StringMapEntry &elem) -> bool { - StringRef filename = AllInputs[elem.second].file(); - return llvm::sys::path::extension(filename).endswith(extension); - }); +bool FrontendInputsAndOutputs::areAllNonPrimariesSIB() const { + for (const InputFile &input : AllInputs) { + if (input.isPrimary()) + continue; + if (!llvm::sys::path::extension(input.file()).endswith(SIB_EXTENSION)) { + return false; + } + } + return true; } bool FrontendInputsAndOutputs::verifyInputs(DiagnosticEngine &diags, @@ -171,13 +210,25 @@ bool FrontendInputsAndOutputs::verifyInputs(DiagnosticEngine &diags, return false; } -bool FrontendInputsAndOutputs::areAllNonPrimariesSIB() const { - for (const InputFile &input : AllInputs) { - if (input.isPrimary()) - continue; - if (!llvm::sys::path::extension(input.file()).endswith(SIB_EXTENSION)) { - return false; - } - } - return true; +// Changing inputs + +void FrontendInputsAndOutputs::clearInputs() { + AllInputs.clear(); + PrimaryInputs.clear(); +} + +void FrontendInputsAndOutputs::addInput(const InputFile &input) { + if (!input.file().empty() && input.isPrimary()) + PrimaryInputs.insert(std::make_pair(input.file(), AllInputs.size())); + AllInputs.push_back(input); +} + +void FrontendInputsAndOutputs::addInputFile(StringRef file, + llvm::MemoryBuffer *buffer) { + addInput(InputFile(file, false, buffer)); +} + +void FrontendInputsAndOutputs::addPrimaryInputFile(StringRef file, + llvm::MemoryBuffer *buffer) { + addInput(InputFile(file, true, buffer)); }