Skip to content

Commit 36496ae

Browse files
author
David Ungar
authored
Merge pull request #14001 from davidungar/PR-18-3a
[Batch mode] Move various Frontend pieces into dedicated files.
2 parents 6ec935a + a70ba0a commit 36496ae

11 files changed

+1368
-1117
lines changed
Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
//===--- ArgsToFrontendInputsConverter.h ------------------------*- C++ -*-===//
2+
//
3+
// This source file is part of the Swift.org open source project
4+
//
5+
// Copyright (c) 2014 - 2018 Apple Inc. and the Swift project authors
6+
// Licensed under Apache License v2.0 with Runtime Library Exception
7+
//
8+
// See https://swift.org/LICENSE.txt for license information
9+
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
10+
//
11+
//===----------------------------------------------------------------------===//
12+
13+
#ifndef SWIFT_FRONTEND_ARGSTOFRONTENDINPUTSCONVERTER_H
14+
#define SWIFT_FRONTEND_ARGSTOFRONTENDINPUTSCONVERTER_H
15+
16+
#include "swift/AST/DiagnosticConsumer.h"
17+
#include "swift/AST/DiagnosticEngine.h"
18+
#include "swift/Frontend/FrontendOptions.h"
19+
#include "llvm/Option/ArgList.h"
20+
21+
namespace swift {
22+
23+
/// Implement argument semantics in a way that will make it easier to have
24+
/// >1 primary file (or even a primary file list) in the future without
25+
/// breaking anything today.
26+
///
27+
/// Semantics today:
28+
/// If input files are on command line, primary files on command line are also
29+
/// input files; they are not repeated without -primary-file. If input files are
30+
/// in a file list, the primary files on the command line are repeated in the
31+
/// file list. Thus, if there are any primary files, it is illegal to have both
32+
/// (non-primary) input files and a file list. Finally, the order of input files
33+
/// must match the order given on the command line or the file list.
34+
///
35+
/// Side note:
36+
/// since each input file will cause a lot of work for the compiler, this code
37+
/// is biased towards clarity and not optimized.
38+
/// In the near future, it will be possible to put primary files in the
39+
/// filelist, or to have a separate filelist for primaries. The organization
40+
/// here anticipates that evolution.
41+
42+
class ArgsToFrontendInputsConverter {
43+
DiagnosticEngine &Diags;
44+
const llvm::opt::ArgList &Args;
45+
FrontendInputs &Inputs;
46+
47+
llvm::opt::Arg const *const FilelistPathArg;
48+
llvm::opt::Arg const *const PrimaryFilelistPathArg;
49+
50+
SmallVector<std::unique_ptr<llvm::MemoryBuffer>, 4> BuffersToKeepAlive;
51+
52+
llvm::SetVector<StringRef> Files;
53+
54+
public:
55+
ArgsToFrontendInputsConverter(DiagnosticEngine &diags,
56+
const llvm::opt::ArgList &args,
57+
FrontendInputs &inputs);
58+
59+
bool convert();
60+
61+
private:
62+
bool enforceFilelistExclusion();
63+
bool readInputFilesFromCommandLine();
64+
bool readInputFilesFromFilelist();
65+
bool forAllFilesInFilelist(llvm::opt::Arg const *const pathArg,
66+
llvm::function_ref<void(StringRef)> fn);
67+
bool addFile(StringRef file);
68+
Optional<std::set<StringRef>> readPrimaryFiles();
69+
std::set<StringRef>
70+
createInputFilesConsumingPrimaries(std::set<StringRef> primaryFiles);
71+
bool checkForMissingPrimaryFiles(std::set<StringRef> primaryFiles);
72+
};
73+
74+
} // namespace swift
75+
76+
#endif /* SWIFT_FRONTEND_ARGSTOFRONTENDINPUTSCONVERTER_H */
Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
1+
//===------ArgsToFrontendOptionsConverter.h-- --------------------*-C++ -*-===//
2+
//
3+
// This source file is part of the Swift.org open source project
4+
//
5+
// Copyright (c) 2014 - 2018 Apple Inc. and the Swift project authors
6+
// Licensed under Apache License v2.0 with Runtime Library Exception
7+
//
8+
// See https://swift.org/LICENSE.txt for license information
9+
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
10+
//
11+
//===----------------------------------------------------------------------===//
12+
13+
#ifndef SWIFT_FRONTEND_ARGSTOFRONTENDOPTIONSCONVERTER_H
14+
#define SWIFT_FRONTEND_ARGSTOFRONTENDOPTIONSCONVERTER_H
15+
16+
#include "swift/AST/DiagnosticConsumer.h"
17+
#include "swift/AST/DiagnosticEngine.h"
18+
#include "swift/Frontend/FrontendOptions.h"
19+
#include "swift/Option/Options.h"
20+
#include "llvm/Option/ArgList.h"
21+
22+
#include <vector>
23+
24+
namespace swift {
25+
26+
class ArgsToFrontendOptionsConverter {
27+
private:
28+
DiagnosticEngine &Diags;
29+
const llvm::opt::ArgList &Args;
30+
FrontendOptions &Opts;
31+
32+
Optional<const std::vector<std::string>>
33+
cachedOutputFilenamesFromCommandLineOrFilelist;
34+
35+
void handleDebugCrashGroupArguments();
36+
37+
void computeDebugTimeOptions();
38+
bool computeFallbackModuleName();
39+
bool computeModuleName();
40+
bool computeOutputFilenames();
41+
void computeDumpScopeMapLocations();
42+
void computeHelpOptions();
43+
void computeImplicitImportModuleNames();
44+
void computeImportObjCHeaderOptions();
45+
void computeLLVMArgs();
46+
void computePlaygroundOptions();
47+
void computePrintStatsOptions();
48+
void computeTBDOptions();
49+
50+
void setUnsignedIntegerArgument(options::ID optionID, unsigned max,
51+
unsigned &valueToSet);
52+
53+
FrontendOptions::ActionType determineRequestedAction() const;
54+
55+
bool setUpForSILOrLLVM();
56+
57+
/// Determine the correct output filename when none was specified.
58+
///
59+
/// Such an absence should only occur when invoking the frontend
60+
/// without the driver,
61+
/// because the driver will always pass -o with an appropriate filename
62+
/// if output is required for the requested action.
63+
bool deriveOutputFilenameFromInputFile();
64+
65+
/// Determine the correct output filename when a directory was specified.
66+
///
67+
/// Such a specification should only occur when invoking the frontend
68+
/// directly, because the driver will always pass -o with an appropriate
69+
/// filename if output is required for the requested action.
70+
bool deriveOutputFilenameForDirectory(StringRef outputDir);
71+
72+
std::string determineBaseNameOfOutput() const;
73+
74+
void deriveOutputFilenameFromParts(StringRef dir, StringRef base);
75+
76+
void determineSupplementaryOutputFilenames();
77+
78+
/// Returns the output filenames on the command line or in the output
79+
/// filelist. If there
80+
/// were neither -o's nor an output filelist, returns an empty vector.
81+
ArrayRef<std::string> getOutputFilenamesFromCommandLineOrFilelist();
82+
83+
bool checkForUnusedOutputPaths() const;
84+
85+
std::vector<std::string> readOutputFileList(StringRef filelistPath) const;
86+
87+
public:
88+
ArgsToFrontendOptionsConverter(DiagnosticEngine &Diags,
89+
const llvm::opt::ArgList &Args,
90+
FrontendOptions &Opts)
91+
: Diags(Diags), Args(Args), Opts(Opts) {}
92+
93+
bool convert();
94+
};
95+
96+
} // namespace swift
97+
98+
#endif /* SWIFT_FRONTEND_ARGSTOFRONTENDOPTIONSCONVERTER_H */
Lines changed: 127 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,127 @@
1+
//===--- FrontendInputs.h ---------------------------------------*- C++ -*-===//
2+
//
3+
// This source file is part of the Swift.org open source project
4+
//
5+
// Copyright (c) 2014 - 2018 Apple Inc. and the Swift project authors
6+
// Licensed under Apache License v2.0 with Runtime Library Exception
7+
//
8+
// See https://swift.org/LICENSE.txt for license information
9+
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
10+
//
11+
//===----------------------------------------------------------------------===//
12+
13+
#ifndef SWIFT_FRONTEND_FRONTENDINPUTS_H
14+
#define SWIFT_FRONTEND_FRONTENDINPUTS_H
15+
16+
#include "swift/AST/Module.h"
17+
#include "swift/Frontend/FrontendInputs.h"
18+
#include "swift/Frontend/InputFile.h"
19+
#include "llvm/ADT/Hashing.h"
20+
#include "llvm/ADT/MapVector.h"
21+
22+
#include <string>
23+
#include <vector>
24+
25+
namespace llvm {
26+
class MemoryBuffer;
27+
}
28+
29+
namespace swift {
30+
31+
/// Information about all the inputs to the frontend.
32+
class FrontendInputs {
33+
friend class ArgsToFrontendInputsConverter;
34+
35+
std::vector<InputFile> AllFiles;
36+
typedef llvm::StringMap<unsigned> InputFileMap;
37+
InputFileMap PrimaryInputs;
38+
39+
public:
40+
FrontendInputs() = default;
41+
42+
FrontendInputs(const FrontendInputs &other);
43+
44+
FrontendInputs &operator=(const FrontendInputs &other);
45+
46+
// Readers:
47+
48+
ArrayRef<InputFile> getAllFiles() const { return AllFiles; }
49+
50+
std::vector<std::string> getInputFilenames() const;
51+
52+
unsigned inputCount() const { return getAllFiles().size(); }
53+
54+
bool hasInputs() const { return !AllFiles.empty(); }
55+
56+
bool hasSingleInput() const { return inputCount() == 1; }
57+
58+
StringRef getFilenameOfFirstInput() const;
59+
60+
bool isReadingFromStdin() const;
61+
62+
// If we have exactly one input filename, and its extension is "bc" or "ll",
63+
// treat the input as LLVM_IR.
64+
bool shouldTreatAsLLVM() const;
65+
66+
// Primary input readers
67+
68+
private:
69+
void assertMustNotBeMoreThanOnePrimaryInput() const;
70+
71+
bool areAllNonPrimariesSIB() const;
72+
73+
public:
74+
unsigned primaryInputCount() const { return PrimaryInputs.size(); }
75+
76+
// Primary count readers:
77+
78+
bool hasUniquePrimaryInput() const { return primaryInputCount() == 1; }
79+
80+
bool hasPrimaryInputs() const { return primaryInputCount() > 0; }
81+
82+
bool isWholeModule() const { return !hasPrimaryInputs(); }
83+
84+
// Count-dependend readers:
85+
86+
/// \return the unique primary input, if one exists.
87+
const InputFile *getUniquePrimaryInput() const;
88+
89+
const InputFile &getRequiredUniquePrimaryInput() const;
90+
91+
/// \return the name of the unique primary input, or an empty StrinRef if
92+
/// there isn't one.
93+
StringRef getNameOfUniquePrimaryInputFile() const;
94+
95+
bool isFilePrimary(StringRef file) const;
96+
97+
unsigned numberOfPrimaryInputsEndingWith(const char *extension) const;
98+
99+
// Multi-facet readers
100+
101+
bool shouldTreatAsSIL() const;
102+
103+
/// \return true for error
104+
bool verifyInputs(DiagnosticEngine &diags, bool treatAsSIL,
105+
bool isREPLRequested, bool isNoneRequested) const;
106+
107+
// Writers
108+
109+
void addInputFile(StringRef file, llvm::MemoryBuffer *buffer = nullptr) {
110+
addInput(InputFile(file, false, buffer));
111+
}
112+
void addPrimaryInputFile(StringRef file,
113+
llvm::MemoryBuffer *buffer = nullptr) {
114+
addInput(InputFile(file, true, buffer));
115+
}
116+
117+
void addInput(const InputFile &input);
118+
119+
void clearInputs() {
120+
AllFiles.clear();
121+
PrimaryInputs.clear();
122+
}
123+
};
124+
125+
} // namespace swift
126+
127+
#endif /* SWIFT_FRONTEND_FRONTENDINPUTS_H */

0 commit comments

Comments
 (0)