mirror of
https://github.com/apple/swift.git
synced 2025-12-21 12:14:44 +01:00
Incorperate advice from review.
Change “have” routines to “has”. Use more consistent casing. Remove spurious “DelayedFunctionParsing” option. Move debugFail routines to top lexical level. Rename and reorder declaration of functions in FrontendArgsToOptionsConverter. Move, reword, and doxygenate comments for some of those functions. Fix casing on some more setUp* functions. Return NoneAction instead of existing RequestedAction in FrontendArgsToOptionsConverter::determineRequestedAction. Remove test names and put in FIXME’s. Remove “Jordan” from comments & reword. Reorder if-then arms of FrontendArgsToOptionsConverter::computeOutputFilenames for readability. Test for empty string instead of equality with “”. Use hasUnusedModuleDocOutputPath. Remove optionality from return type of getOutputFilenamesFromCommandLineOrFilelist. Rename isPrimaryInputAFileAt to isThereAPrimaryInputWithAFilenameAt. Added a FIXME in doesActionProduceOutput to reflect that some actions actually do not produce output.
This commit is contained in:
@@ -84,17 +84,17 @@ public:
|
|||||||
|
|
||||||
// Input filename readers
|
// Input filename readers
|
||||||
ArrayRef<std::string> getInputFilenames() const { return InputFilenames; }
|
ArrayRef<std::string> getInputFilenames() const { return InputFilenames; }
|
||||||
bool haveInputFilenames() const { return !getInputFilenames().empty(); }
|
bool hasInputFilenames() const { return !getInputFilenames().empty(); }
|
||||||
unsigned inputFilenameCount() const { return getInputFilenames().size(); }
|
unsigned inputFilenameCount() const { return getInputFilenames().size(); }
|
||||||
|
|
||||||
bool haveUniqueInputFilename() const { return inputFilenameCount() == 1; }
|
bool hasUniqueInputFilename() const { return inputFilenameCount() == 1; }
|
||||||
const std::string &getFilenameOfFirstInput() const {
|
const std::string &getFilenameOfFirstInput() const {
|
||||||
assert(haveInputFilenames());
|
assert(hasInputFilenames());
|
||||||
return getInputFilenames()[0];
|
return getInputFilenames()[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
bool isReadingFromStdin() const {
|
bool isReadingFromStdin() const {
|
||||||
return haveUniqueInputFilename() && getFilenameOfFirstInput() == "-";
|
return hasUniqueInputFilename() && getFilenameOfFirstInput() == "-";
|
||||||
}
|
}
|
||||||
|
|
||||||
// If we have exactly one input filename, and its extension is "bc" or "ll",
|
// If we have exactly one input filename, and its extension is "bc" or "ll",
|
||||||
@@ -123,32 +123,32 @@ public:
|
|||||||
|
|
||||||
// Primary count readers:
|
// Primary count readers:
|
||||||
|
|
||||||
bool haveUniquePrimaryInput() const { return primaryInputCount() == 1; }
|
bool hasUniquePrimaryInput() const { return primaryInputCount() == 1; }
|
||||||
|
|
||||||
bool havePrimaryInputs() const { return primaryInputCount() > 0; }
|
bool hasPrimaryInputs() const { return primaryInputCount() > 0; }
|
||||||
|
|
||||||
bool isWholeModule() const { return !havePrimaryInputs(); }
|
bool isWholeModule() const { return !hasPrimaryInputs(); }
|
||||||
|
|
||||||
// Count-dependend readers:
|
// Count-dependend readers:
|
||||||
|
|
||||||
Optional<SelectedInput> getOptionalPrimaryInput() const {
|
Optional<SelectedInput> getOptionalPrimaryInput() const {
|
||||||
return havePrimaryInputs() ? Optional<SelectedInput>(getPrimaryInputs()[0])
|
return hasPrimaryInputs() ? Optional<SelectedInput>(getPrimaryInputs()[0])
|
||||||
: Optional<SelectedInput>();
|
: Optional<SelectedInput>();
|
||||||
}
|
}
|
||||||
|
|
||||||
SelectedInput getRequiredUniquePrimaryInput() const {
|
SelectedInput getRequiredUniquePrimaryInput() const {
|
||||||
assert(haveUniquePrimaryInput());
|
assert(hasUniquePrimaryInput());
|
||||||
return getPrimaryInputs()[0];
|
return getPrimaryInputs()[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
Optional<SelectedInput> getOptionalUniquePrimaryInput() const {
|
Optional<SelectedInput> getOptionalUniquePrimaryInput() const {
|
||||||
return haveUniquePrimaryInput()
|
return hasUniquePrimaryInput()
|
||||||
? Optional<SelectedInput>(getPrimaryInputs()[0])
|
? Optional<SelectedInput>(getPrimaryInputs()[0])
|
||||||
: Optional<SelectedInput>();
|
: Optional<SelectedInput>();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool haveAPrimaryInputFile() const {
|
bool hasAPrimaryInputFile() const {
|
||||||
return havePrimaryInputs() && getOptionalPrimaryInput()->isFilename();
|
return hasPrimaryInputs() && getOptionalPrimaryInput()->isFilename();
|
||||||
}
|
}
|
||||||
|
|
||||||
Optional<StringRef> getOptionalUniquePrimaryInputFilename() const {
|
Optional<StringRef> getOptionalUniquePrimaryInputFilename() const {
|
||||||
@@ -158,7 +158,7 @@ public:
|
|||||||
: Optional<StringRef>();
|
: Optional<StringRef>();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool isPrimaryInputAFileAt(unsigned i) const {
|
bool isThereAPrimaryInputWithAFilenameAt(unsigned i) const {
|
||||||
assertMustNotBeMoreThanOnePrimaryInput();
|
assertMustNotBeMoreThanOnePrimaryInput();
|
||||||
if (Optional<SelectedInput> primaryInput = getOptionalPrimaryInput())
|
if (Optional<SelectedInput> primaryInput = getOptionalPrimaryInput())
|
||||||
return primaryInput->isFilename() && primaryInput->Index == i;
|
return primaryInput->isFilename() && primaryInput->Index == i;
|
||||||
@@ -166,7 +166,7 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
Optional<unsigned> primaryInputFileIndex() const {
|
Optional<unsigned> primaryInputFileIndex() const {
|
||||||
return haveAPrimaryInputFile()
|
return hasAPrimaryInputFile()
|
||||||
? Optional<unsigned>(getOptionalPrimaryInput()->Index)
|
? Optional<unsigned>(getOptionalPrimaryInput()->Index)
|
||||||
: None;
|
: None;
|
||||||
}
|
}
|
||||||
@@ -183,7 +183,7 @@ public:
|
|||||||
bool shouldTreatAsSIL() const;
|
bool shouldTreatAsSIL() const;
|
||||||
|
|
||||||
/// Return true for error
|
/// Return true for error
|
||||||
bool verifyInputs(DiagnosticEngine &Diags, bool TreatAsSIL,
|
bool verifyInputs(DiagnosticEngine &diags, bool treatAsSIL,
|
||||||
bool isREPLRequested, bool isNoneRequested) const;
|
bool isREPLRequested, bool isNoneRequested) const;
|
||||||
|
|
||||||
// Input filename writers
|
// Input filename writers
|
||||||
@@ -274,7 +274,7 @@ public:
|
|||||||
return getSingleOutputFilename() == "-";
|
return getSingleOutputFilename() == "-";
|
||||||
}
|
}
|
||||||
bool isOutputFileDirectory() const;
|
bool isOutputFileDirectory() const;
|
||||||
bool haveNamedOutputFile() const {
|
bool hasNamedOutputFile() const {
|
||||||
return !OutputFilenames.empty() && !isOutputFilenameStdout();
|
return !OutputFilenames.empty() && !isOutputFilenameStdout();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -424,10 +424,6 @@ public:
|
|||||||
/// Trace changes to stats to files in StatsOutputDir.
|
/// Trace changes to stats to files in StatsOutputDir.
|
||||||
bool TraceStats = false;
|
bool TraceStats = false;
|
||||||
|
|
||||||
/// Indicates whether function body parsing should be delayed
|
|
||||||
/// until the end of all files.
|
|
||||||
bool DelayedFunctionBodyParsing = false;
|
|
||||||
|
|
||||||
/// If true, serialization encodes an extra lookup table for use in module-
|
/// If true, serialization encodes an extra lookup table for use in module-
|
||||||
/// merging when emitting partial modules (the per-file modules in a non-WMO
|
/// merging when emitting partial modules (the per-file modules in a non-WMO
|
||||||
/// build).
|
/// build).
|
||||||
@@ -536,7 +532,7 @@ public:
|
|||||||
|
|
||||||
bool isCompilingExactlyOneSwiftFile() const {
|
bool isCompilingExactlyOneSwiftFile() const {
|
||||||
return InputKind == InputFileKind::IFK_Swift &&
|
return InputKind == InputFileKind::IFK_Swift &&
|
||||||
Inputs.haveUniqueInputFilename();
|
Inputs.hasUniqueInputFilename();
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|||||||
@@ -79,6 +79,18 @@ SourceFileKind CompilerInvocation::getSourceFileKind() const {
|
|||||||
llvm_unreachable("Unhandled InputFileKind in switch.");
|
llvm_unreachable("Unhandled InputFileKind in switch.");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// This is a separate function so that it shows up in stack traces.
|
||||||
|
LLVM_ATTRIBUTE_NOINLINE
|
||||||
|
static void debugFailWithAssertion() {
|
||||||
|
// This assertion should always fail, per the user's request, and should
|
||||||
|
// not be converted to llvm_unreachable.
|
||||||
|
assert(0 && "This is an assertion!");
|
||||||
|
}
|
||||||
|
|
||||||
|
// This is a separate function so that it shows up in stack traces.
|
||||||
|
LLVM_ATTRIBUTE_NOINLINE
|
||||||
|
static void debugFailWithCrash() { LLVM_BUILTIN_TRAP; }
|
||||||
|
|
||||||
namespace swift {
|
namespace swift {
|
||||||
|
|
||||||
/// Implement argument semantics in a way that will make it easier to have
|
/// Implement argument semantics in a way that will make it easier to have
|
||||||
@@ -224,50 +236,58 @@ private:
|
|||||||
const llvm::opt::ArgList &Args;
|
const llvm::opt::ArgList &Args;
|
||||||
FrontendOptions &Opts;
|
FrontendOptions &Opts;
|
||||||
|
|
||||||
llvm::Optional<const std::vector<std::string>>
|
Optional<const std::vector<std::string>>
|
||||||
cachedOutputFilenamesFromCommandLineOrFilelist;
|
cachedOutputFilenamesFromCommandLineOrFilelist;
|
||||||
|
|
||||||
// This is a separate function so that it shows up in stack traces.
|
void handleDebugCrashGroupArguments();
|
||||||
LLVM_ATTRIBUTE_NOINLINE
|
|
||||||
static void debugFailWithAssertion() {
|
|
||||||
// This assertion should always fail, per the user's request, and should
|
|
||||||
// not be converted to llvm_unreachable.
|
|
||||||
assert(0 && "This is an assertion!");
|
|
||||||
}
|
|
||||||
|
|
||||||
// This is a separate function so that it shows up in stack traces.
|
|
||||||
LLVM_ATTRIBUTE_NOINLINE
|
|
||||||
static void debugFailWithCrash() { LLVM_BUILTIN_TRAP; }
|
|
||||||
|
|
||||||
void computeDebugCrashGroup();
|
|
||||||
void computeDebugTimeOptions();
|
void computeDebugTimeOptions();
|
||||||
|
bool computeFallbackModuleName();
|
||||||
|
bool computeModuleName();
|
||||||
|
bool computeOutputFilenames();
|
||||||
|
void computeDumpScopeMapLocations();
|
||||||
|
void computeHelpOptions();
|
||||||
|
void computeImplicitImportModuleNames();
|
||||||
|
void computeImportObjCHeaderOptions();
|
||||||
|
void computeLLVMArgs();
|
||||||
|
void computePlaygroundOptions();
|
||||||
void computePrintStatsOptions();
|
void computePrintStatsOptions();
|
||||||
void computeTBDOptions();
|
void computeTBDOptions();
|
||||||
|
|
||||||
void setUnsignedIntegerArgument(options::ID optionID, unsigned max,
|
void setUnsignedIntegerArgument(options::ID optionID, unsigned max,
|
||||||
unsigned &valueToSet);
|
unsigned &valueToSet);
|
||||||
void computePlaygroundOptions();
|
|
||||||
void computeHelpOptions();
|
|
||||||
void computeDumpScopeMapLocations();
|
|
||||||
FrontendOptions::ActionType determineRequestedAction() const;
|
FrontendOptions::ActionType determineRequestedAction() const;
|
||||||
bool setupForSILOrLLVM();
|
|
||||||
bool computeModuleName();
|
bool setUpForSILOrLLVM();
|
||||||
bool computeFallbackModuleName();
|
|
||||||
bool computeOutputFilenames();
|
/// Determine the correct output filename when none was specified.
|
||||||
|
///
|
||||||
|
/// Such an absence should only occur when invoking the frontend
|
||||||
|
/// without the driver,
|
||||||
|
/// because the driver will always pass -o with an appropriate filename
|
||||||
|
/// if output is required for the requested action.
|
||||||
bool deriveOutputFilenameFromInputFile();
|
bool deriveOutputFilenameFromInputFile();
|
||||||
bool deriveOutputFilenameForDirectory(llvm::StringRef outputDir);
|
|
||||||
std::string computeBaseNameOfOutput() const;
|
/// Determine the correct output filename when a directory was specified.
|
||||||
|
///
|
||||||
|
/// Such a specification should only occur when invoking the frontend
|
||||||
|
/// directly, because the driver will always pass -o with an appropriate
|
||||||
|
/// filename if output is required for the requested action.
|
||||||
|
bool deriveOutputFilenameForDirectory(StringRef outputDir);
|
||||||
|
|
||||||
|
std::string determineBaseNameOfOutput() const;
|
||||||
|
|
||||||
void determineSupplementaryOutputFilenames();
|
void determineSupplementaryOutputFilenames();
|
||||||
|
|
||||||
/// Returns the output filenames on the command line or in the output
|
/// Returns the output filenames on the command line or in the output
|
||||||
/// filelist. If there was an error (reading the list) returns None. If there
|
/// filelist. If there
|
||||||
/// were neither -o's nor an output filelist, returns an empty vector.
|
/// were neither -o's nor an output filelist, returns an empty vector.
|
||||||
const llvm::Optional<const std::vector<std::string>> &
|
const std::vector<std::string> &getOutputFilenamesFromCommandLineOrFilelist();
|
||||||
getOutputFilenamesFromCommandLineOrFilelist();
|
|
||||||
bool hasAnUnusedOutputPath() const;
|
bool checkForUnusedOutputPaths() const;
|
||||||
void computeImportObjCHeaderOptions();
|
|
||||||
void computeImplicitImportModuleNames();
|
std::vector<std::string> readOutputFileList(StringRef filelistPath) const;
|
||||||
void computeLLVMArgs();
|
|
||||||
const std::vector<std::string>
|
|
||||||
readOutputFileList(const StringRef filelistPath) const;
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
FrontendArgsToOptionsConverter(DiagnosticEngine &Diags,
|
FrontendArgsToOptionsConverter(DiagnosticEngine &Diags,
|
||||||
@@ -282,7 +302,7 @@ public:
|
|||||||
bool FrontendArgsToOptionsConverter::convert() {
|
bool FrontendArgsToOptionsConverter::convert() {
|
||||||
using namespace options;
|
using namespace options;
|
||||||
|
|
||||||
computeDebugCrashGroup();
|
handleDebugCrashGroupArguments();
|
||||||
|
|
||||||
if (const Arg *A = Args.getLastArg(OPT_dump_api_path)) {
|
if (const Arg *A = Args.getLastArg(OPT_dump_api_path)) {
|
||||||
Opts.DumpAPIPath = A->getValue();
|
Opts.DumpAPIPath = A->getValue();
|
||||||
@@ -298,8 +318,6 @@ bool FrontendArgsToOptionsConverter::convert() {
|
|||||||
Opts.EmitVerboseSIL |= Args.hasArg(OPT_emit_verbose_sil);
|
Opts.EmitVerboseSIL |= Args.hasArg(OPT_emit_verbose_sil);
|
||||||
Opts.EmitSortedSIL |= Args.hasArg(OPT_emit_sorted_sil);
|
Opts.EmitSortedSIL |= Args.hasArg(OPT_emit_sorted_sil);
|
||||||
|
|
||||||
Opts.DelayedFunctionBodyParsing |=
|
|
||||||
Args.hasArg(OPT_delayed_function_body_parsing);
|
|
||||||
Opts.EnableTesting |= Args.hasArg(OPT_enable_testing);
|
Opts.EnableTesting |= Args.hasArg(OPT_enable_testing);
|
||||||
Opts.EnableResilience |= Args.hasArg(OPT_enable_resilience);
|
Opts.EnableResilience |= Args.hasArg(OPT_enable_resilience);
|
||||||
|
|
||||||
@@ -333,12 +351,12 @@ bool FrontendArgsToOptionsConverter::convert() {
|
|||||||
Opts.RequestedAction = determineRequestedAction();
|
Opts.RequestedAction = determineRequestedAction();
|
||||||
|
|
||||||
if (Opts.RequestedAction == FrontendOptions::ActionType::Immediate &&
|
if (Opts.RequestedAction == FrontendOptions::ActionType::Immediate &&
|
||||||
Opts.Inputs.havePrimaryInputs()) {
|
Opts.Inputs.hasPrimaryInputs()) {
|
||||||
Diags.diagnose(SourceLoc(), diag::error_immediate_mode_primary_file);
|
Diags.diagnose(SourceLoc(), diag::error_immediate_mode_primary_file);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (setupForSILOrLLVM())
|
if (setUpForSILOrLLVM())
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
if (computeModuleName())
|
if (computeModuleName())
|
||||||
@@ -348,7 +366,7 @@ bool FrontendArgsToOptionsConverter::convert() {
|
|||||||
return true;
|
return true;
|
||||||
determineSupplementaryOutputFilenames();
|
determineSupplementaryOutputFilenames();
|
||||||
|
|
||||||
if (hasAnUnusedOutputPath())
|
if (checkForUnusedOutputPaths())
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
if (const Arg *A = Args.getLastArg(OPT_module_link_name)) {
|
if (const Arg *A = Args.getLastArg(OPT_module_link_name)) {
|
||||||
@@ -369,7 +387,7 @@ bool FrontendArgsToOptionsConverter::convert() {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void FrontendArgsToOptionsConverter::computeDebugCrashGroup() {
|
void FrontendArgsToOptionsConverter::handleDebugCrashGroupArguments() {
|
||||||
using namespace options;
|
using namespace options;
|
||||||
|
|
||||||
if (const Arg *A = Args.getLastArg(OPT_debug_crash_Group)) {
|
if (const Arg *A = Args.getLastArg(OPT_debug_crash_Group)) {
|
||||||
@@ -515,7 +533,7 @@ FrontendArgsToOptionsConverter::determineRequestedAction() const {
|
|||||||
// (Setting up module output will be handled below.)
|
// (Setting up module output will be handled below.)
|
||||||
return FrontendOptions::ActionType::EmitModuleOnly;
|
return FrontendOptions::ActionType::EmitModuleOnly;
|
||||||
}
|
}
|
||||||
return Opts.RequestedAction; // no change
|
return FrontendOptions::ActionType::NoneAction;
|
||||||
}
|
}
|
||||||
Option Opt = A->getOption();
|
Option Opt = A->getOption();
|
||||||
if (Opt.matches(OPT_emit_object))
|
if (Opt.matches(OPT_emit_object))
|
||||||
@@ -567,14 +585,14 @@ FrontendArgsToOptionsConverter::determineRequestedAction() const {
|
|||||||
llvm_unreachable("Unhandled mode option");
|
llvm_unreachable("Unhandled mode option");
|
||||||
}
|
}
|
||||||
|
|
||||||
bool FrontendArgsToOptionsConverter::setupForSILOrLLVM() {
|
bool FrontendArgsToOptionsConverter::setUpForSILOrLLVM() {
|
||||||
using namespace options;
|
using namespace options;
|
||||||
bool TreatAsSIL =
|
bool treatAsSIL =
|
||||||
Args.hasArg(OPT_parse_sil) || Opts.Inputs.shouldTreatAsSIL();
|
Args.hasArg(OPT_parse_sil) || Opts.Inputs.shouldTreatAsSIL();
|
||||||
bool TreatAsLLVM = Opts.Inputs.shouldTreatAsLLVM();
|
bool treatAsLLVM = Opts.Inputs.shouldTreatAsLLVM();
|
||||||
|
|
||||||
if (Opts.Inputs.verifyInputs(
|
if (Opts.Inputs.verifyInputs(
|
||||||
Diags, TreatAsSIL,
|
Diags, treatAsSIL,
|
||||||
Opts.RequestedAction == FrontendOptions::ActionType::REPL,
|
Opts.RequestedAction == FrontendOptions::ActionType::REPL,
|
||||||
Opts.RequestedAction == FrontendOptions::ActionType::NoneAction)) {
|
Opts.RequestedAction == FrontendOptions::ActionType::NoneAction)) {
|
||||||
return true;
|
return true;
|
||||||
@@ -589,9 +607,9 @@ bool FrontendArgsToOptionsConverter::setupForSILOrLLVM() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (TreatAsSIL)
|
if (treatAsSIL)
|
||||||
Opts.InputKind = InputFileKind::IFK_SIL;
|
Opts.InputKind = InputFileKind::IFK_SIL;
|
||||||
else if (TreatAsLLVM)
|
else if (treatAsLLVM)
|
||||||
Opts.InputKind = InputFileKind::IFK_LLVM_IR;
|
Opts.InputKind = InputFileKind::IFK_LLVM_IR;
|
||||||
else if (Args.hasArg(OPT_parse_as_library))
|
else if (Args.hasArg(OPT_parse_as_library))
|
||||||
Opts.InputKind = InputFileKind::IFK_Swift_Library;
|
Opts.InputKind = InputFileKind::IFK_Swift_Library;
|
||||||
@@ -630,8 +648,8 @@ bool FrontendArgsToOptionsConverter::computeModuleName() {
|
|||||||
: diag::error_bad_module_name;
|
: diag::error_bad_module_name;
|
||||||
Diags.diagnose(SourceLoc(), DID, Opts.ModuleName, A == nullptr);
|
Diags.diagnose(SourceLoc(), DID, Opts.ModuleName, A == nullptr);
|
||||||
Opts.ModuleName = "__bad__";
|
Opts.ModuleName = "__bad__";
|
||||||
return false; // Must continue to run to pass test:
|
return false; // FIXME: Must continue to run to pass the tests, but should not
|
||||||
// multifile.protocol-conformance.swift
|
// have to.
|
||||||
}
|
}
|
||||||
|
|
||||||
bool FrontendArgsToOptionsConverter::computeFallbackModuleName() {
|
bool FrontendArgsToOptionsConverter::computeFallbackModuleName() {
|
||||||
@@ -640,27 +658,22 @@ bool FrontendArgsToOptionsConverter::computeFallbackModuleName() {
|
|||||||
Opts.ModuleName = "REPL";
|
Opts.ModuleName = "REPL";
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
// In order to pass Driver/options.swift test must leave ModuleName empty
|
if (!Opts.Inputs.hasInputFilenames()) {
|
||||||
if (!Opts.Inputs.haveInputFilenames()) {
|
|
||||||
Opts.ModuleName = StringRef();
|
Opts.ModuleName = StringRef();
|
||||||
// Jordan thinks this is a bug that should not happen, & asked me to report
|
// FIXME: This is a bug that should not happen, but does in tests.
|
||||||
// back if it does. It does happen in, for example,
|
// The current behavior is needed to pass the tests.
|
||||||
// test/Frontend/no-arguments.swift
|
// The compiler should bail out earlier, where "no frontend action was
|
||||||
// The first test is: RUN: not %swift 2>&1 | %FileCheck %s
|
// selected".
|
||||||
// -check-prefix=CHECK1 Which invokes swift with no input arguments and
|
|
||||||
// expects the following error: "no frontend action was selected"
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
const llvm::Optional<const std::vector<std::string>> &outputFilenames =
|
const std::vector<std::string> &outputFilenames =
|
||||||
getOutputFilenamesFromCommandLineOrFilelist();
|
getOutputFilenamesFromCommandLineOrFilelist();
|
||||||
if (!outputFilenames)
|
|
||||||
return true;
|
|
||||||
|
|
||||||
bool isOutputAUniqueOrdinaryFile =
|
bool isOutputAUniqueOrdinaryFile =
|
||||||
outputFilenames->size() == 1 && (*outputFilenames)[0] != "-" &&
|
outputFilenames.size() == 1 && outputFilenames[0] != "-" &&
|
||||||
!llvm::sys::fs::is_directory((*outputFilenames)[0]);
|
!llvm::sys::fs::is_directory(outputFilenames[0]);
|
||||||
std::string nameToStem = isOutputAUniqueOrdinaryFile
|
std::string nameToStem = isOutputAUniqueOrdinaryFile
|
||||||
? (*outputFilenames)[0]
|
? outputFilenames[0]
|
||||||
: Opts.Inputs.getFilenameOfFirstInput();
|
: Opts.Inputs.getFilenameOfFirstInput();
|
||||||
Opts.ModuleName = llvm::sys::path::stem(nameToStem);
|
Opts.ModuleName = llvm::sys::path::stem(nameToStem);
|
||||||
return false;
|
return false;
|
||||||
@@ -671,48 +684,40 @@ bool FrontendArgsToOptionsConverter::computeOutputFilenames() {
|
|||||||
FrontendOptions::doesActionProduceOutput(Opts.RequestedAction) ||
|
FrontendOptions::doesActionProduceOutput(Opts.RequestedAction) ||
|
||||||
!FrontendOptions::doesActionProduceTextualOutput(Opts.RequestedAction));
|
!FrontendOptions::doesActionProduceTextualOutput(Opts.RequestedAction));
|
||||||
|
|
||||||
const llvm::Optional<const std::vector<std::string>>
|
const std::vector<std::string> &outputFilenamesFromCommandLineOrFilelist =
|
||||||
&outputFilenamesFromCommandLineOrFilelist =
|
getOutputFilenamesFromCommandLineOrFilelist();
|
||||||
getOutputFilenamesFromCommandLineOrFilelist();
|
|
||||||
|
|
||||||
if (!outputFilenamesFromCommandLineOrFilelist)
|
if (outputFilenamesFromCommandLineOrFilelist.size() > 1) {
|
||||||
return true;
|
// WMO, threaded with N files (also someday batch mode).
|
||||||
|
Opts.OutputFilenames = outputFilenamesFromCommandLineOrFilelist;
|
||||||
// Filelist names do not get altered.
|
|
||||||
if (outputFilenamesFromCommandLineOrFilelist->empty()) {
|
|
||||||
// Frontend was invoked directly, without driver.
|
|
||||||
return deriveOutputFilenameFromInputFile();
|
|
||||||
}
|
|
||||||
if (outputFilenamesFromCommandLineOrFilelist->size() == 1) {
|
|
||||||
StringRef outputFilename = (*outputFilenamesFromCommandLineOrFilelist)[0];
|
|
||||||
if (llvm::sys::fs::is_directory(outputFilename)) {
|
|
||||||
// Only used for testing & when invoking frontend directly.
|
|
||||||
return deriveOutputFilenameForDirectory(outputFilename);
|
|
||||||
}
|
|
||||||
// Could be -primary-file (1), or -wmo (non-threaded w/ N files)
|
|
||||||
Opts.OutputFilenames = *outputFilenamesFromCommandLineOrFilelist;
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
// WMO, threaded with N files (also someday batch mode).
|
|
||||||
Opts.OutputFilenames = *outputFilenamesFromCommandLineOrFilelist;
|
if (outputFilenamesFromCommandLineOrFilelist.empty()) {
|
||||||
return false;
|
// When the Frontend is invoked without going through the driver
|
||||||
|
// (e.g. for testing), it is convenient to derive output filenames from
|
||||||
|
// input.
|
||||||
|
return deriveOutputFilenameFromInputFile();
|
||||||
|
}
|
||||||
|
|
||||||
|
StringRef outputFilename = outputFilenamesFromCommandLineOrFilelist[0];
|
||||||
|
if (!llvm::sys::fs::is_directory(outputFilename)) {
|
||||||
|
// Could be -primary-file (1), or -wmo (non-threaded w/ N (input) files)
|
||||||
|
Opts.OutputFilenames = outputFilenamesFromCommandLineOrFilelist;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
// Only used for testing & when invoking frontend directly.
|
||||||
|
return deriveOutputFilenameForDirectory(outputFilename);
|
||||||
}
|
}
|
||||||
|
|
||||||
// No output filename was specified.
|
|
||||||
// Determine the correct output filename.
|
|
||||||
|
|
||||||
// Note: this should typically only be used when invoking the frontend
|
|
||||||
// directly, as the driver will always pass -o with an appropriate filename
|
|
||||||
// if output is required for the requested action.
|
|
||||||
|
|
||||||
bool FrontendArgsToOptionsConverter::deriveOutputFilenameFromInputFile() {
|
bool FrontendArgsToOptionsConverter::deriveOutputFilenameFromInputFile() {
|
||||||
if (Opts.Inputs.isReadingFromStdin() ||
|
if (Opts.Inputs.isReadingFromStdin() ||
|
||||||
FrontendOptions::doesActionProduceTextualOutput(Opts.RequestedAction)) {
|
FrontendOptions::doesActionProduceTextualOutput(Opts.RequestedAction)) {
|
||||||
Opts.setOutputFilenameToStdout();
|
Opts.setOutputFilenameToStdout();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
std::string baseName = computeBaseNameOfOutput();
|
std::string baseName = determineBaseNameOfOutput();
|
||||||
if (baseName == "") {
|
if (baseName.empty()) {
|
||||||
if (Opts.RequestedAction != FrontendOptions::ActionType::REPL &&
|
if (Opts.RequestedAction != FrontendOptions::ActionType::REPL &&
|
||||||
Opts.RequestedAction != FrontendOptions::ActionType::Immediate &&
|
Opts.RequestedAction != FrontendOptions::ActionType::Immediate &&
|
||||||
Opts.RequestedAction != FrontendOptions::ActionType::NoneAction) {
|
Opts.RequestedAction != FrontendOptions::ActionType::NoneAction) {
|
||||||
@@ -721,47 +726,41 @@ bool FrontendArgsToOptionsConverter::deriveOutputFilenameFromInputFile() {
|
|||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
llvm::SmallString<128> Path(baseName);
|
llvm::SmallString<128> path(baseName);
|
||||||
StringRef Suffix = FrontendOptions::suffixForPrincipalOutputFileForAction(
|
StringRef suffix = FrontendOptions::suffixForPrincipalOutputFileForAction(
|
||||||
Opts.RequestedAction);
|
Opts.RequestedAction);
|
||||||
llvm::sys::path::replace_extension(Path, Suffix);
|
llvm::sys::path::replace_extension(path, suffix);
|
||||||
Opts.OutputFilenames.push_back(Path.str());
|
Opts.OutputFilenames.push_back(path.str());
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// An output directory was specified.
|
|
||||||
// Determine the correct output filename.
|
|
||||||
|
|
||||||
// Note: this should typically only be used when invoking the frontend
|
|
||||||
// directly, as the driver will always pass -o with an appropriate filename
|
|
||||||
// if output is required for the requested action.
|
|
||||||
bool FrontendArgsToOptionsConverter::deriveOutputFilenameForDirectory(
|
bool FrontendArgsToOptionsConverter::deriveOutputFilenameForDirectory(
|
||||||
StringRef outputDir) {
|
StringRef outputDir) {
|
||||||
|
|
||||||
std::string baseName = computeBaseNameOfOutput();
|
std::string baseName = determineBaseNameOfOutput();
|
||||||
if (baseName == "") {
|
if (baseName.empty()) {
|
||||||
Diags.diagnose(SourceLoc(), diag::error_implicit_output_file_is_directory,
|
Diags.diagnose(SourceLoc(), diag::error_implicit_output_file_is_directory,
|
||||||
outputDir);
|
outputDir);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
llvm::SmallString<128> Path(outputDir);
|
llvm::SmallString<128> path(outputDir);
|
||||||
llvm::sys::path::append(Path, baseName);
|
llvm::sys::path::append(path, baseName);
|
||||||
StringRef Suffix = FrontendOptions::suffixForPrincipalOutputFileForAction(
|
StringRef suffix = FrontendOptions::suffixForPrincipalOutputFileForAction(
|
||||||
Opts.RequestedAction);
|
Opts.RequestedAction);
|
||||||
llvm::sys::path::replace_extension(Path, Suffix);
|
llvm::sys::path::replace_extension(path, suffix);
|
||||||
Opts.OutputFilenames.push_back(Path.str());
|
Opts.OutputFilenames.push_back(path.str());
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string FrontendArgsToOptionsConverter::computeBaseNameOfOutput() const {
|
std::string FrontendArgsToOptionsConverter::determineBaseNameOfOutput() const {
|
||||||
std::string nameToStem;
|
std::string nameToStem;
|
||||||
if (Opts.Inputs.haveAPrimaryInputFile()) {
|
if (Opts.Inputs.hasAPrimaryInputFile()) {
|
||||||
assert(Opts.Inputs.haveUniquePrimaryInput() &&
|
assert(Opts.Inputs.hasUniquePrimaryInput() &&
|
||||||
"Cannot handle multiple primaries yet");
|
"Cannot handle multiple primaries yet");
|
||||||
nameToStem = Opts.Inputs.primaryInputFilenameIfAny();
|
nameToStem = Opts.Inputs.primaryInputFilenameIfAny();
|
||||||
} else if (auto UserSpecifiedModuleName =
|
} else if (auto UserSpecifiedModuleName =
|
||||||
Args.getLastArg(options::OPT_module_name)) {
|
Args.getLastArg(options::OPT_module_name)) {
|
||||||
nameToStem = std::string(UserSpecifiedModuleName->getValue());
|
nameToStem = UserSpecifiedModuleName->getValue();
|
||||||
} else if (Opts.Inputs.inputFilenameCount() == 1) {
|
} else if (Opts.Inputs.inputFilenameCount() == 1) {
|
||||||
nameToStem = Opts.Inputs.getFilenameOfFirstInput();
|
nameToStem = Opts.Inputs.getFilenameOfFirstInput();
|
||||||
} else
|
} else
|
||||||
@@ -792,9 +791,9 @@ void FrontendArgsToOptionsConverter::determineSupplementaryOutputFilenames() {
|
|||||||
if (!output.empty())
|
if (!output.empty())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
llvm::SmallString<128> Path(Opts.originalPath());
|
llvm::SmallString<128> path(Opts.originalPath());
|
||||||
llvm::sys::path::replace_extension(Path, extension);
|
llvm::sys::path::replace_extension(path, extension);
|
||||||
output = Path.str();
|
output = path.str();
|
||||||
};
|
};
|
||||||
|
|
||||||
determineOutputFilename(Opts.DependenciesFilePath, OPT_emit_dependencies,
|
determineOutputFilename(Opts.DependenciesFilePath, OPT_emit_dependencies,
|
||||||
@@ -818,18 +817,18 @@ void FrontendArgsToOptionsConverter::determineSupplementaryOutputFilenames() {
|
|||||||
Opts.FixitsOutputPath = A->getValue();
|
Opts.FixitsOutputPath = A->getValue();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool IsSIB = Opts.RequestedAction == FrontendOptions::ActionType::EmitSIB ||
|
bool isSIB = Opts.RequestedAction == FrontendOptions::ActionType::EmitSIB ||
|
||||||
Opts.RequestedAction == FrontendOptions::ActionType::EmitSIBGen;
|
Opts.RequestedAction == FrontendOptions::ActionType::EmitSIBGen;
|
||||||
bool canUseMainOutputForModule =
|
bool canUseMainOutputForModule =
|
||||||
Opts.RequestedAction == FrontendOptions::ActionType::MergeModules ||
|
Opts.RequestedAction == FrontendOptions::ActionType::MergeModules ||
|
||||||
Opts.RequestedAction == FrontendOptions::ActionType::EmitModuleOnly ||
|
Opts.RequestedAction == FrontendOptions::ActionType::EmitModuleOnly ||
|
||||||
IsSIB;
|
isSIB;
|
||||||
auto ext = IsSIB ? SIB_EXTENSION : SERIALIZED_MODULE_EXTENSION;
|
auto ext = isSIB ? SIB_EXTENSION : SERIALIZED_MODULE_EXTENSION;
|
||||||
auto sibOpt = Opts.RequestedAction == FrontendOptions::ActionType::EmitSIB
|
auto sibOpt = Opts.RequestedAction == FrontendOptions::ActionType::EmitSIB
|
||||||
? OPT_emit_sib
|
? OPT_emit_sib
|
||||||
: OPT_emit_sibgen;
|
: OPT_emit_sibgen;
|
||||||
determineOutputFilename(Opts.ModuleOutputPath,
|
determineOutputFilename(Opts.ModuleOutputPath,
|
||||||
IsSIB ? sibOpt : OPT_emit_module,
|
isSIB ? sibOpt : OPT_emit_module,
|
||||||
OPT_emit_module_path, ext, canUseMainOutputForModule);
|
OPT_emit_module_path, ext, canUseMainOutputForModule);
|
||||||
|
|
||||||
determineOutputFilename(Opts.ModuleDocOutputPath, OPT_emit_module_doc,
|
determineOutputFilename(Opts.ModuleDocOutputPath, OPT_emit_module_doc,
|
||||||
@@ -837,7 +836,7 @@ void FrontendArgsToOptionsConverter::determineSupplementaryOutputFilenames() {
|
|||||||
SERIALIZED_MODULE_DOC_EXTENSION, false);
|
SERIALIZED_MODULE_DOC_EXTENSION, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool FrontendArgsToOptionsConverter::hasAnUnusedOutputPath() const {
|
bool FrontendArgsToOptionsConverter::checkForUnusedOutputPaths() const {
|
||||||
if (Opts.hasUnusedDependenciesFilePath()) {
|
if (Opts.hasUnusedDependenciesFilePath()) {
|
||||||
Diags.diagnose(SourceLoc(), diag::error_mode_cannot_emit_dependencies);
|
Diags.diagnose(SourceLoc(), diag::error_mode_cannot_emit_dependencies);
|
||||||
return true;
|
return true;
|
||||||
@@ -855,7 +854,7 @@ bool FrontendArgsToOptionsConverter::hasAnUnusedOutputPath() const {
|
|||||||
Diags.diagnose(SourceLoc(), diag::error_mode_cannot_emit_module);
|
Diags.diagnose(SourceLoc(), diag::error_mode_cannot_emit_module);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
if (Opts.hasUnusedModuleOutputPath()) {
|
if (Opts.hasUnusedModuleDocOutputPath()) {
|
||||||
Diags.diagnose(SourceLoc(), diag::error_mode_cannot_emit_module_doc);
|
Diags.diagnose(SourceLoc(), diag::error_mode_cannot_emit_module_doc);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -867,7 +866,7 @@ void FrontendArgsToOptionsConverter::computeImportObjCHeaderOptions() {
|
|||||||
if (const Arg *A = Args.getLastArgNoClaim(OPT_import_objc_header)) {
|
if (const Arg *A = Args.getLastArgNoClaim(OPT_import_objc_header)) {
|
||||||
Opts.ImplicitObjCHeaderPath = A->getValue();
|
Opts.ImplicitObjCHeaderPath = A->getValue();
|
||||||
Opts.SerializeBridgingHeader |=
|
Opts.SerializeBridgingHeader |=
|
||||||
!Opts.Inputs.havePrimaryInputs() && !Opts.ModuleOutputPath.empty();
|
!Opts.Inputs.hasPrimaryInputs() && !Opts.ModuleOutputPath.empty();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
void FrontendArgsToOptionsConverter::computeImplicitImportModuleNames() {
|
void FrontendArgsToOptionsConverter::computeImplicitImportModuleNames() {
|
||||||
@@ -883,10 +882,10 @@ void FrontendArgsToOptionsConverter::computeLLVMArgs() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const llvm::Optional<const std::vector<std::string>> &
|
const std::vector<std::string> &
|
||||||
FrontendArgsToOptionsConverter::getOutputFilenamesFromCommandLineOrFilelist() {
|
FrontendArgsToOptionsConverter::getOutputFilenamesFromCommandLineOrFilelist() {
|
||||||
if (cachedOutputFilenamesFromCommandLineOrFilelist) {
|
if (cachedOutputFilenamesFromCommandLineOrFilelist) {
|
||||||
return cachedOutputFilenamesFromCommandLineOrFilelist;
|
return *cachedOutputFilenamesFromCommandLineOrFilelist;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (const Arg *A = Args.getLastArg(options::OPT_output_filelist)) {
|
if (const Arg *A = Args.getLastArg(options::OPT_output_filelist)) {
|
||||||
@@ -898,12 +897,11 @@ FrontendArgsToOptionsConverter::getOutputFilenamesFromCommandLineOrFilelist() {
|
|||||||
cachedOutputFilenamesFromCommandLineOrFilelist.emplace(
|
cachedOutputFilenamesFromCommandLineOrFilelist.emplace(
|
||||||
Args.getAllArgValues(options::OPT_o));
|
Args.getAllArgValues(options::OPT_o));
|
||||||
}
|
}
|
||||||
return cachedOutputFilenamesFromCommandLineOrFilelist;
|
return *cachedOutputFilenamesFromCommandLineOrFilelist;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Try to read an output file list file.
|
/// Try to read an output file list file.
|
||||||
const std::vector<std::string>
|
std::vector<std::string> FrontendArgsToOptionsConverter::readOutputFileList(
|
||||||
FrontendArgsToOptionsConverter::readOutputFileList(
|
|
||||||
const StringRef filelistPath) const {
|
const StringRef filelistPath) const {
|
||||||
llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>> buffer =
|
llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>> buffer =
|
||||||
llvm::MemoryBuffer::getFile(filelistPath);
|
llvm::MemoryBuffer::getFile(filelistPath);
|
||||||
@@ -918,9 +916,9 @@ FrontendArgsToOptionsConverter::readOutputFileList(
|
|||||||
return outputFiles;
|
return outputFiles;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool ParseFrontendArgs(FrontendOptions &Opts, ArgList &Args,
|
static bool ParseFrontendArgs(FrontendOptions &opts, ArgList &args,
|
||||||
DiagnosticEngine &Diags) {
|
DiagnosticEngine &diags) {
|
||||||
return FrontendArgsToOptionsConverter(Diags, Args, Opts).convert();
|
return FrontendArgsToOptionsConverter(diags, args, opts).convert();
|
||||||
}
|
}
|
||||||
|
|
||||||
static void diagnoseSwiftVersion(Optional<version::Version> &vers, Arg *verArg,
|
static void diagnoseSwiftVersion(Optional<version::Version> &vers, Arg *verArg,
|
||||||
@@ -1652,7 +1650,7 @@ static bool ParseIRGenArgs(IRGenOptions &Opts, ArgList &Args,
|
|||||||
} else if (const Optional<StringRef> filename =
|
} else if (const Optional<StringRef> filename =
|
||||||
FrontendOpts.Inputs.getOptionalUniquePrimaryInputFilename()) {
|
FrontendOpts.Inputs.getOptionalUniquePrimaryInputFilename()) {
|
||||||
Opts.MainInputFilename = filename.getValue();
|
Opts.MainInputFilename = filename.getValue();
|
||||||
} else if (FrontendOpts.Inputs.haveUniqueInputFilename()) {
|
} else if (FrontendOpts.Inputs.hasUniqueInputFilename()) {
|
||||||
Opts.MainInputFilename = FrontendOpts.Inputs.getFilenameOfFirstInput();
|
Opts.MainInputFilename = FrontendOpts.Inputs.getFilenameOfFirstInput();
|
||||||
}
|
}
|
||||||
Opts.OutputFilenames = FrontendOpts.OutputFilenames;
|
Opts.OutputFilenames = FrontendOpts.OutputFilenames;
|
||||||
@@ -1884,36 +1882,36 @@ CompilerInvocation::loadFromSerializedAST(StringRef data) {
|
|||||||
|
|
||||||
llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>>
|
llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>>
|
||||||
CompilerInvocation::setUpInputForSILTool(
|
CompilerInvocation::setUpInputForSILTool(
|
||||||
StringRef InputFilename, StringRef ModuleNameArg,
|
StringRef inputFilename, StringRef moduleNameArg,
|
||||||
bool alwaysSetModuleToMain,
|
bool alwaysSetModuleToMain,
|
||||||
serialization::ExtendedValidationInfo &extendedInfo) {
|
serialization::ExtendedValidationInfo &extendedInfo) {
|
||||||
// Load the input file.
|
// Load the input file.
|
||||||
llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>> FileBufOrErr =
|
llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>> fileBufOrErr =
|
||||||
llvm::MemoryBuffer::getFileOrSTDIN(InputFilename);
|
llvm::MemoryBuffer::getFileOrSTDIN(inputFilename);
|
||||||
if (!FileBufOrErr) {
|
if (!fileBufOrErr) {
|
||||||
return FileBufOrErr;
|
return fileBufOrErr;
|
||||||
}
|
}
|
||||||
|
|
||||||
// If it looks like we have an AST, set the source file kind to SIL and the
|
// If it looks like we have an AST, set the source file kind to SIL and the
|
||||||
// name of the module to the file's name.
|
// name of the module to the file's name.
|
||||||
addInputBuffer(FileBufOrErr.get().get());
|
addInputBuffer(fileBufOrErr.get().get());
|
||||||
|
|
||||||
auto result = serialization::validateSerializedAST(
|
auto result = serialization::validateSerializedAST(
|
||||||
FileBufOrErr.get()->getBuffer(), &extendedInfo);
|
fileBufOrErr.get()->getBuffer(), &extendedInfo);
|
||||||
bool HasSerializedAST = result.status == serialization::Status::Valid;
|
bool hasSerializedAST = result.status == serialization::Status::Valid;
|
||||||
|
|
||||||
if (HasSerializedAST) {
|
if (hasSerializedAST) {
|
||||||
const StringRef Stem = !ModuleNameArg.empty()
|
const StringRef stem = !moduleNameArg.empty()
|
||||||
? ModuleNameArg
|
? moduleNameArg
|
||||||
: llvm::sys::path::stem(InputFilename);
|
: llvm::sys::path::stem(inputFilename);
|
||||||
setModuleName(Stem);
|
setModuleName(stem);
|
||||||
setInputKind(InputFileKind::IFK_Swift_Library);
|
setInputKind(InputFileKind::IFK_Swift_Library);
|
||||||
} else {
|
} else {
|
||||||
const StringRef Name = (alwaysSetModuleToMain || ModuleNameArg.empty())
|
const StringRef name = (alwaysSetModuleToMain || moduleNameArg.empty())
|
||||||
? "main"
|
? "main"
|
||||||
: ModuleNameArg;
|
: moduleNameArg;
|
||||||
setModuleName(Name);
|
setModuleName(name);
|
||||||
setInputKind(InputFileKind::IFK_SIL);
|
setInputKind(InputFileKind::IFK_SIL);
|
||||||
}
|
}
|
||||||
return FileBufOrErr;
|
return fileBufOrErr;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -741,7 +741,8 @@ bool CompilerInstance::setUpForFileAt(unsigned i) {
|
|||||||
if (SILMode || (MainMode && filename(File) == "main.swift"))
|
if (SILMode || (MainMode && filename(File) == "main.swift"))
|
||||||
MainBufferID = ExistingBufferID.getValue();
|
MainBufferID = ExistingBufferID.getValue();
|
||||||
|
|
||||||
if (Invocation.getFrontendOptions().Inputs.isPrimaryInputAFileAt(i))
|
if (Invocation.getFrontendOptions()
|
||||||
|
.Inputs.isThereAPrimaryInputWithAFilenameAt(i))
|
||||||
PrimaryBufferID = ExistingBufferID.getValue();
|
PrimaryBufferID = ExistingBufferID.getValue();
|
||||||
|
|
||||||
return false; // replaced by a memory buffer.
|
return false; // replaced by a memory buffer.
|
||||||
@@ -783,7 +784,8 @@ bool CompilerInstance::setUpForFileAt(unsigned i) {
|
|||||||
if (SILMode || (MainMode && filename(File) == "main.swift"))
|
if (SILMode || (MainMode && filename(File) == "main.swift"))
|
||||||
MainBufferID = BufferID;
|
MainBufferID = BufferID;
|
||||||
|
|
||||||
if (Invocation.getFrontendOptions().Inputs.isPrimaryInputAFileAt(i))
|
if (Invocation.getFrontendOptions()
|
||||||
|
.Inputs.isThereAPrimaryInputWithAFilenameAt(i))
|
||||||
PrimaryBufferID = BufferID;
|
PrimaryBufferID = BufferID;
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
|
|||||||
@@ -28,7 +28,7 @@ using namespace swift;
|
|||||||
using namespace llvm::opt;
|
using namespace llvm::opt;
|
||||||
|
|
||||||
bool FrontendInputs::shouldTreatAsLLVM() const {
|
bool FrontendInputs::shouldTreatAsLLVM() const {
|
||||||
if (haveUniqueInputFilename()) {
|
if (hasUniqueInputFilename()) {
|
||||||
StringRef Input(getFilenameOfFirstInput());
|
StringRef Input(getFilenameOfFirstInput());
|
||||||
return llvm::sys::path::extension(Input).endswith(LLVM_BC_EXTENSION) ||
|
return llvm::sys::path::extension(Input).endswith(LLVM_BC_EXTENSION) ||
|
||||||
llvm::sys::path::extension(Input).endswith(LLVM_IR_EXTENSION);
|
llvm::sys::path::extension(Input).endswith(LLVM_IR_EXTENSION);
|
||||||
@@ -37,7 +37,7 @@ bool FrontendInputs::shouldTreatAsLLVM() const {
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool FrontendInputs::shouldTreatAsSIL() const {
|
bool FrontendInputs::shouldTreatAsSIL() const {
|
||||||
if (haveUniqueInputFilename()) {
|
if (hasUniqueInputFilename()) {
|
||||||
// If we have exactly one input filename, and its extension is "sil",
|
// If we have exactly one input filename, and its extension is "sil",
|
||||||
// treat the input as SIL.
|
// treat the input as SIL.
|
||||||
StringRef Input(getFilenameOfFirstInput());
|
StringRef Input(getFilenameOfFirstInput());
|
||||||
@@ -53,36 +53,36 @@ bool FrontendInputs::shouldTreatAsSIL() const {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool FrontendInputs::verifyInputs(DiagnosticEngine &Diags, bool TreatAsSIL,
|
bool FrontendInputs::verifyInputs(DiagnosticEngine &diags, bool treatAsSIL,
|
||||||
bool isREPLRequested,
|
bool isREPLRequested,
|
||||||
bool isNoneRequested) const {
|
bool isNoneRequested) const {
|
||||||
if (isREPLRequested) {
|
if (isREPLRequested) {
|
||||||
if (haveInputFilenames()) {
|
if (hasInputFilenames()) {
|
||||||
Diags.diagnose(SourceLoc(), diag::error_repl_requires_no_input_files);
|
diags.diagnose(SourceLoc(), diag::error_repl_requires_no_input_files);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
} else if (TreatAsSIL && havePrimaryInputs()) {
|
} else if (treatAsSIL && hasPrimaryInputs()) {
|
||||||
// If we have the SIL as our primary input, we can waive the one file
|
// If we have the SIL as our primary input, we can waive the one file
|
||||||
// requirement as long as all the other inputs are SIBs.
|
// requirement as long as all the other inputs are SIBs.
|
||||||
for (unsigned i = 0, e = inputFilenameCount(); i != e; ++i) {
|
for (unsigned i = 0, e = inputFilenameCount(); i != e; ++i) {
|
||||||
if (i == getOptionalUniquePrimaryInput()->Index)
|
if (i == getOptionalUniquePrimaryInput()->Index)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
StringRef File(getInputFilenames()[i]);
|
StringRef file(getInputFilenames()[i]);
|
||||||
if (!llvm::sys::path::extension(File).endswith(SIB_EXTENSION)) {
|
if (!llvm::sys::path::extension(file).endswith(SIB_EXTENSION)) {
|
||||||
Diags.diagnose(SourceLoc(),
|
diags.diagnose(SourceLoc(),
|
||||||
diag::error_mode_requires_one_sil_multi_sib);
|
diag::error_mode_requires_one_sil_multi_sib);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (TreatAsSIL) {
|
} else if (treatAsSIL) {
|
||||||
if (!haveUniqueInputFilename()) {
|
if (!hasUniqueInputFilename()) {
|
||||||
Diags.diagnose(SourceLoc(), diag::error_mode_requires_one_input_file);
|
diags.diagnose(SourceLoc(), diag::error_mode_requires_one_input_file);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
} else if (!isNoneRequested) {
|
} else if (!isNoneRequested) {
|
||||||
if (!haveInputFilenames()) {
|
if (!hasInputFilenames()) {
|
||||||
Diags.diagnose(SourceLoc(), diag::error_mode_requires_an_input_file);
|
diags.diagnose(SourceLoc(), diag::error_mode_requires_an_input_file);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -184,7 +184,7 @@ void FrontendOptions::forAllOutputPaths(
|
|||||||
|
|
||||||
|
|
||||||
StringRef FrontendOptions::originalPath() const {
|
StringRef FrontendOptions::originalPath() const {
|
||||||
if (haveNamedOutputFile())
|
if (hasNamedOutputFile())
|
||||||
// Put the serialized diagnostics file next to the output file.
|
// Put the serialized diagnostics file next to the output file.
|
||||||
return getSingleOutputFilename();
|
return getSingleOutputFilename();
|
||||||
|
|
||||||
@@ -196,7 +196,7 @@ StringRef FrontendOptions::originalPath() const {
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool FrontendOptions::isOutputFileDirectory() const {
|
bool FrontendOptions::isOutputFileDirectory() const {
|
||||||
return haveNamedOutputFile() &&
|
return hasNamedOutputFile() &&
|
||||||
llvm::sys::fs::is_directory(getSingleOutputFilename());
|
llvm::sys::fs::is_directory(getSingleOutputFilename());
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -406,6 +406,8 @@ bool FrontendOptions::canActionEmitModuleDoc(ActionType action) {
|
|||||||
|
|
||||||
bool FrontendOptions::doesActionProduceOutput(ActionType action) {
|
bool FrontendOptions::doesActionProduceOutput(ActionType action) {
|
||||||
switch (action) {
|
switch (action) {
|
||||||
|
// FIXME: Some of these don't actually produce output
|
||||||
|
// but for now stay consistent with the status quo.
|
||||||
case ActionType::NoneAction:
|
case ActionType::NoneAction:
|
||||||
case ActionType::EmitPCH:
|
case ActionType::EmitPCH:
|
||||||
case ActionType::EmitSIBGen:
|
case ActionType::EmitSIBGen:
|
||||||
|
|||||||
@@ -541,7 +541,7 @@ static bool performCompile(CompilerInstance &Instance,
|
|||||||
auto &LLVMContext = getGlobalLLVMContext();
|
auto &LLVMContext = getGlobalLLVMContext();
|
||||||
|
|
||||||
// Load in bitcode file.
|
// Load in bitcode file.
|
||||||
assert(Invocation.getFrontendOptions().Inputs.haveUniqueInputFilename() &&
|
assert(Invocation.getFrontendOptions().Inputs.hasUniqueInputFilename() &&
|
||||||
"We expect a single input for bitcode input!");
|
"We expect a single input for bitcode input!");
|
||||||
llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>> FileBufOrErr =
|
llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>> FileBufOrErr =
|
||||||
llvm::MemoryBuffer::getFileOrSTDIN(
|
llvm::MemoryBuffer::getFileOrSTDIN(
|
||||||
@@ -776,7 +776,7 @@ static bool performCompile(CompilerInstance &Instance,
|
|||||||
auto SASTF = dyn_cast<SerializedASTFile>(File);
|
auto SASTF = dyn_cast<SerializedASTFile>(File);
|
||||||
return SASTF && SASTF->isSIB();
|
return SASTF && SASTF->isSIB();
|
||||||
};
|
};
|
||||||
if (opts.Inputs.haveAPrimaryInputFile()) {
|
if (opts.Inputs.hasAPrimaryInputFile()) {
|
||||||
FileUnit *PrimaryFile = PrimarySourceFile;
|
FileUnit *PrimaryFile = PrimarySourceFile;
|
||||||
if (!PrimaryFile) {
|
if (!PrimaryFile) {
|
||||||
auto Index = opts.Inputs.getRequiredUniquePrimaryInput().Index;
|
auto Index = opts.Inputs.getRequiredUniquePrimaryInput().Index;
|
||||||
|
|||||||
@@ -83,7 +83,7 @@ struct InvocationOptions {
|
|||||||
// Assert invocation with a primary file. We want to avoid full typechecking
|
// Assert invocation with a primary file. We want to avoid full typechecking
|
||||||
// for all files.
|
// for all files.
|
||||||
assert(!this->PrimaryFile.empty());
|
assert(!this->PrimaryFile.empty());
|
||||||
assert(this->Invok.getFrontendOptions().Inputs.haveUniquePrimaryInput() &&
|
assert(this->Invok.getFrontendOptions().Inputs.hasUniquePrimaryInput() &&
|
||||||
"Must have exactly one primary input for code completion, etc.");
|
"Must have exactly one primary input for code completion, etc.");
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -355,7 +355,7 @@ static void setModuleName(CompilerInvocation &Invocation) {
|
|||||||
|
|
||||||
StringRef Filename = Invocation.getOutputFilename();
|
StringRef Filename = Invocation.getOutputFilename();
|
||||||
if (Filename.empty()) {
|
if (Filename.empty()) {
|
||||||
if (!Invocation.getFrontendOptions().Inputs.haveInputFilenames()) {
|
if (!Invocation.getFrontendOptions().Inputs.hasInputFilenames()) {
|
||||||
Invocation.setModuleName("__main__");
|
Invocation.setModuleName("__main__");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -144,7 +144,7 @@ static bool swiftCodeCompleteImpl(SwiftLangSupport &Lang,
|
|||||||
if (Failed) {
|
if (Failed) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (!Invocation.getFrontendOptions().Inputs.haveInputFilenames()) {
|
if (!Invocation.getFrontendOptions().Inputs.hasInputFilenames()) {
|
||||||
Error = "no input filenames specified";
|
Error = "no input filenames specified";
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -279,7 +279,7 @@ void SwiftLangSupport::indexSource(StringRef InputFile,
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!Invocation.getFrontendOptions().Inputs.haveInputFilenames()) {
|
if (!Invocation.getFrontendOptions().Inputs.hasInputFilenames()) {
|
||||||
IdxConsumer.failed("no input filenames specified");
|
IdxConsumer.failed("no input filenames specified");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -43,7 +43,7 @@ private:
|
|||||||
std::vector<std::string> InputFilenames;
|
std::vector<std::string> InputFilenames;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
bool haveUniqueInputFilename() const { return InputFilenames.size() == 1; }
|
bool hasUniqueInputFilename() const { return InputFilenames.size() == 1; }
|
||||||
const std::string &getFilenameOfFirstInput() const {
|
const std::string &getFilenameOfFirstInput() const {
|
||||||
return InputFilenames[0];
|
return InputFilenames[0];
|
||||||
}
|
}
|
||||||
@@ -131,7 +131,7 @@ int modulewrap_main(ArrayRef<const char *> Args, const char *Argv0,
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!Invocation.haveUniqueInputFilename()) {
|
if (!Invocation.hasUniqueInputFilename()) {
|
||||||
Instance.getDiags().diagnose(SourceLoc(),
|
Instance.getDiags().diagnose(SourceLoc(),
|
||||||
diag::error_mode_requires_one_input_file);
|
diag::error_mode_requires_one_input_file);
|
||||||
return 1;
|
return 1;
|
||||||
|
|||||||
Reference in New Issue
Block a user