1 //===- FrontendOptions.h ----------------------------------------*- C -*-===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 #ifndef LLVM_FLANG_FRONTEND_FRONTENDOPTIONS_H
9 #define LLVM_FLANG_FRONTEND_FRONTENDOPTIONS_H
10
11 #include "llvm/ADT/StringRef.h"
12 #include "llvm/Support/MemoryBuffer.h"
13
14 #include <cstdint>
15 #include <string>
16
17 namespace Fortran::frontend {
18
19 enum ActionKind {
20 InvalidAction = 0,
21
22 /// -test-io mode
23 InputOutputTest,
24
25 /// -E mode.
26 PrintPreprocessedInput,
27 /// TODO: RunPreprocessor, ParserSyntaxOnly, EmitLLVM, EmitLLVMOnly,
28 /// EmitCodeGenOnly, EmitAssembly, (...)
29 };
30
GetActionKindName(const ActionKind ak)31 inline const char *GetActionKindName(const ActionKind ak) {
32 switch (ak) {
33 case InputOutputTest:
34 return "InputOutputTest";
35 case PrintPreprocessedInput:
36 return "PrintPreprocessedInput";
37 default:
38 return "<unknown ActionKind>";
39 // TODO:
40 // case RunPreprocessor:
41 // case ParserSyntaxOnly:
42 // case EmitLLVM:
43 // case EmitLLVMOnly:
44 // case EmitCodeGenOnly:
45 // (...)
46 }
47 }
48
49 enum class Language : uint8_t {
50 Unknown,
51
52 /// LLVM IR: we accept this so that we can run the optimizer on it,
53 /// and compile it to assembly or object code.
54 LLVM_IR,
55
56 /// @{ Languages that the frontend can parse and compile.
57 Fortran,
58 };
59
60 /// The kind of a file that we've been handed as an input.
61 class InputKind {
62 private:
63 Language lang_;
64
65 public:
66 /// The input file format.
67 enum Format { Source, ModuleMap, Precompiled };
68
lang_(l)69 constexpr InputKind(Language l = Language::Unknown) : lang_(l) {}
70
GetLanguage()71 Language GetLanguage() const { return static_cast<Language>(lang_); }
72
73 /// Is the input kind fully-unknown?
IsUnknown()74 bool IsUnknown() const { return lang_ == Language::Unknown; }
75 };
76
77 /// An input file for the front end.
78 class FrontendInputFile {
79 /// The file name, or "-" to read from standard input.
80 std::string file_;
81
82 /// The input, if it comes from a buffer rather than a file. This object
83 /// does not own the buffer, and the caller is responsible for ensuring
84 /// that it outlives any users.
85 const llvm::MemoryBuffer *buffer_ = nullptr;
86
87 /// The kind of input, atm it contains language
88 InputKind kind_;
89
90 public:
91 FrontendInputFile() = default;
FrontendInputFile(llvm::StringRef file,InputKind kind)92 FrontendInputFile(llvm::StringRef file, InputKind kind)
93 : file_(file.str()), kind_(kind) {}
FrontendInputFile(const llvm::MemoryBuffer * buffer,InputKind kind)94 FrontendInputFile(const llvm::MemoryBuffer *buffer, InputKind kind)
95 : buffer_(buffer), kind_(kind) {}
96
kind()97 InputKind kind() const { return kind_; }
98
IsEmpty()99 bool IsEmpty() const { return file_.empty() && buffer_ == nullptr; }
IsFile()100 bool IsFile() const { return !IsBuffer(); }
IsBuffer()101 bool IsBuffer() const { return buffer_ != nullptr; }
102
file()103 llvm::StringRef file() const {
104 assert(IsFile());
105 return file_;
106 }
107
buffer()108 const llvm::MemoryBuffer *buffer() const {
109 assert(IsBuffer() && "Requested buffer_, but it is empty!");
110 return buffer_;
111 }
112 };
113
114 /// FrontendOptions - Options for controlling the behavior of the frontend.
115 class FrontendOptions {
116 public:
117 /// Show the -help text.
118 unsigned showHelp_ : 1;
119
120 /// Show the -version text.
121 unsigned showVersion_ : 1;
122
123 /// The input files and their types.
124 std::vector<FrontendInputFile> inputs_;
125
126 /// The output file, if any.
127 std::string outputFile_;
128
129 /// The frontend action to perform.
130 frontend::ActionKind programAction_;
131
132 public:
FrontendOptions()133 FrontendOptions() : showHelp_(false), showVersion_(false) {}
134
135 // Return the appropriate input kind for a file extension. For example,
136 /// "*.f" would return Language::Fortran.
137 ///
138 /// \return The input kind for the extension, or Language::Unknown if the
139 /// extension is not recognized.
140 static InputKind GetInputKindForExtension(llvm::StringRef extension);
141 };
142 } // namespace Fortran::frontend
143
144 #endif // LLVM_FLANG_FRONTEND_FRONTENDOPTIONS_H
145