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
2124namespace 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
4950public:
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
0 commit comments