Warning: This file is not a C or C++ file. It does not have highlighting.
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 | // |
9 | // Coding style: https://mlir.llvm.org/getting_started/DeveloperGuide/ |
10 | // |
11 | //===----------------------------------------------------------------------===// |
12 | |
13 | #ifndef FORTRAN_FRONTEND_FRONTENDOPTIONS_H |
14 | #define FORTRAN_FRONTEND_FRONTENDOPTIONS_H |
15 | |
16 | #include "flang/Common/Fortran-features.h" |
17 | #include "flang/Lower/EnvironmentDefault.h" |
18 | #include "flang/Parser/characters.h" |
19 | #include "flang/Parser/unparse.h" |
20 | #include "llvm/ADT/StringRef.h" |
21 | #include "llvm/Support/MemoryBuffer.h" |
22 | #include <cstdint> |
23 | #include <string> |
24 | |
25 | namespace Fortran::frontend { |
26 | |
27 | enum ActionKind { |
28 | /// -test-io mode |
29 | InputOutputTest, |
30 | |
31 | /// -E mode |
32 | PrintPreprocessedInput, |
33 | |
34 | /// -fsyntax-only |
35 | ParseSyntaxOnly, |
36 | |
37 | /// Emit FIR mlir file |
38 | EmitFIR, |
39 | |
40 | /// Emit HLFIR mlir file |
41 | EmitHLFIR, |
42 | |
43 | /// Emit an .ll file |
44 | EmitLLVM, |
45 | |
46 | /// Emit a .bc file |
47 | EmitLLVMBitcode, |
48 | |
49 | /// Emit a .o file. |
50 | EmitObj, |
51 | |
52 | /// Emit a .s file. |
53 | EmitAssembly, |
54 | |
55 | /// Parse, unparse the parse-tree and output a Fortran source file |
56 | DebugUnparse, |
57 | |
58 | /// Parse, unparse the parse-tree and output a Fortran source file, skip the |
59 | /// semantic checks |
60 | DebugUnparseNoSema, |
61 | |
62 | /// Parse, resolve the sybmols, unparse the parse-tree and then output a |
63 | /// Fortran source file |
64 | DebugUnparseWithSymbols, |
65 | |
66 | /// Parse, run semantics and then output symbols from semantics |
67 | DebugDumpSymbols, |
68 | |
69 | /// Parse, run semantics and then output the parse tree |
70 | DebugDumpParseTree, |
71 | |
72 | /// Parse, run semantics and then output the pre-fir parse tree |
73 | DebugDumpPFT, |
74 | |
75 | /// Parse, run semantics and then output the parse tree and symbols |
76 | DebugDumpAll, |
77 | |
78 | /// Parse and then output the parse tree, skip the semantic checks |
79 | DebugDumpParseTreeNoSema, |
80 | |
81 | /// Dump provenance |
82 | DebugDumpProvenance, |
83 | |
84 | /// Parse then output the parsing log |
85 | DebugDumpParsingLog, |
86 | |
87 | /// Parse then output the number of objects in the parse tree and the overall |
88 | /// size |
89 | DebugMeasureParseTree, |
90 | |
91 | /// Parse, run semantics and then output the pre-FIR tree |
92 | DebugPreFIRTree, |
93 | |
94 | /// `-fget-definition` |
95 | GetDefinition, |
96 | |
97 | /// Parse, run semantics and then dump symbol sources map |
98 | GetSymbolsSources, |
99 | |
100 | /// Only execute frontend initialization |
101 | InitOnly, |
102 | |
103 | /// Run a plugin action |
104 | PluginAction |
105 | }; |
106 | |
107 | /// \param suffix The file extension |
108 | /// \return True if the file extension should be processed as fixed form |
109 | bool isFixedFormSuffix(llvm::StringRef suffix); |
110 | |
111 | /// \param suffix The file extension |
112 | /// \return True if the file extension should be processed as free form |
113 | bool isFreeFormSuffix(llvm::StringRef suffix); |
114 | |
115 | /// \param suffix The file extension |
116 | /// \return True if the file should be preprocessed |
117 | bool isToBePreprocessed(llvm::StringRef suffix); |
118 | |
119 | /// \param suffix The file extension |
120 | /// \return True if the file contains CUDA Fortran |
121 | bool isCUDAFortranSuffix(llvm::StringRef suffix); |
122 | |
123 | enum class Language : uint8_t { |
124 | Unknown, |
125 | |
126 | /// MLIR: we accept this so that we can run the optimizer on it, and compile |
127 | /// it to LLVM IR, assembly or object code. |
128 | MLIR, |
129 | |
130 | /// LLVM IR: we accept this so that we can run the optimizer on it, |
131 | /// and compile it to assembly or object code. |
132 | LLVM_IR, |
133 | |
134 | /// @{ Languages that the frontend can parse and compile. |
135 | Fortran, |
136 | /// @} |
137 | }; |
138 | |
139 | // Source file layout |
140 | enum class FortranForm { |
141 | /// The user has not specified a form. Base the form off the file extension. |
142 | Unknown, |
143 | |
144 | /// -ffree-form |
145 | FixedForm, |
146 | |
147 | /// -ffixed-form |
148 | FreeForm |
149 | }; |
150 | |
151 | /// The kind of a file that we've been handed as an input. |
152 | class InputKind { |
153 | private: |
154 | Language lang; |
155 | |
156 | public: |
157 | /// The input file format. |
158 | enum Format { Source, ModuleMap, Precompiled }; |
159 | |
160 | constexpr InputKind(Language l = Language::Unknown) : lang(l) {} |
161 | |
162 | Language getLanguage() const { return static_cast<Language>(lang); } |
163 | |
164 | /// Is the input kind fully-unknown? |
165 | bool isUnknown() const { return lang == Language::Unknown; } |
166 | }; |
167 | |
168 | /// An input file for the front end. |
169 | class FrontendInputFile { |
170 | /// The file name, or "-" to read from standard input. |
171 | std::string file; |
172 | |
173 | /// The input, if it comes from a buffer rather than a file. This object |
174 | /// does not own the buffer, and the caller is responsible for ensuring |
175 | /// that it outlives any users. |
176 | const llvm::MemoryBuffer *buffer = nullptr; |
177 | |
178 | /// The kind of input, atm it contains language |
179 | InputKind kind; |
180 | |
181 | /// Is this input file in fixed-form format? This is simply derived from the |
182 | /// file extension and should not be altered by consumers. For input from |
183 | /// stdin this is never modified. |
184 | bool isFixedForm = false; |
185 | |
186 | /// Must this file be preprocessed? Note that in Flang the preprocessor is |
187 | /// always run. This flag is used to control whether predefined and command |
188 | /// line preprocessor macros are enabled or not. In practice, this is |
189 | /// sufficient to implement gfortran`s logic controlled with `-cpp/-nocpp`. |
190 | unsigned mustBePreprocessed : 1; |
191 | |
192 | /// Whether to enable CUDA Fortran language extensions |
193 | bool isCUDAFortran{false}; |
194 | |
195 | public: |
196 | FrontendInputFile() = default; |
197 | FrontendInputFile(llvm::StringRef file, InputKind inKind) |
198 | : file(file.str()), kind(inKind) { |
199 | |
200 | // Based on the extension, decide whether this is a fixed or free form |
201 | // file. |
202 | auto pathDotIndex{file.rfind(".")}; |
203 | std::string pathSuffix{file.substr(pathDotIndex + 1)}; |
204 | isFixedForm = isFixedFormSuffix(pathSuffix); |
205 | mustBePreprocessed = isToBePreprocessed(pathSuffix); |
206 | isCUDAFortran = isCUDAFortranSuffix(pathSuffix); |
207 | } |
208 | |
209 | FrontendInputFile(const llvm::MemoryBuffer *memBuf, InputKind inKind) |
210 | : buffer(memBuf), kind(inKind) {} |
211 | |
212 | InputKind getKind() const { return kind; } |
213 | |
214 | bool isEmpty() const { return file.empty() && buffer == nullptr; } |
215 | bool isFile() const { return (buffer == nullptr); } |
216 | bool getIsFixedForm() const { return isFixedForm; } |
217 | bool getMustBePreprocessed() const { return mustBePreprocessed; } |
218 | bool getIsCUDAFortran() const { return isCUDAFortran; } |
219 | |
220 | llvm::StringRef getFile() const { |
221 | assert(isFile()); |
222 | return file; |
223 | } |
224 | |
225 | const llvm::MemoryBuffer *getBuffer() const { |
226 | assert(buffer && "Requested buffer, but it is empty!"); |
227 | return buffer; |
228 | } |
229 | }; |
230 | |
231 | /// FrontendOptions - Options for controlling the behavior of the frontend. |
232 | struct FrontendOptions { |
233 | FrontendOptions() |
234 | : showHelp(false), showVersion(false), instrumentedParse(false), |
235 | showColors(false), needProvenanceRangeToCharBlockMappings(false) {} |
236 | |
237 | /// Show the -help text. |
238 | unsigned showHelp : 1; |
239 | |
240 | /// Show the -version text. |
241 | unsigned showVersion : 1; |
242 | |
243 | /// Instrument the parse to get a more verbose log |
244 | unsigned instrumentedParse : 1; |
245 | |
246 | /// Enable color diagnostics. |
247 | unsigned showColors : 1; |
248 | |
249 | /// Enable Provenance to character-stream mapping. Allows e.g. IDEs to find |
250 | /// symbols based on source-code location. This is not needed in regular |
251 | /// compilation. |
252 | unsigned needProvenanceRangeToCharBlockMappings : 1; |
253 | |
254 | /// Input values from `-fget-definition` |
255 | struct GetDefinitionVals { |
256 | unsigned line; |
257 | unsigned startColumn; |
258 | unsigned endColumn; |
259 | }; |
260 | GetDefinitionVals getDefVals; |
261 | |
262 | /// The input files and their types. |
263 | std::vector<FrontendInputFile> inputs; |
264 | |
265 | /// The output file, if any. |
266 | std::string outputFile; |
267 | |
268 | /// The frontend action to perform. |
269 | frontend::ActionKind programAction = ParseSyntaxOnly; |
270 | |
271 | // The form to process files in, if specified. |
272 | FortranForm fortranForm = FortranForm::Unknown; |
273 | |
274 | // Default values for environment variables to be set by the runtime. |
275 | std::vector<Fortran::lower::EnvironmentDefault> envDefaults; |
276 | |
277 | // The column after which characters are ignored in fixed form lines in the |
278 | // source file. |
279 | int fixedFormColumns = 72; |
280 | |
281 | /// The input kind, either specified via -x argument or deduced from the input |
282 | /// file name. |
283 | InputKind dashX; |
284 | |
285 | // Language features |
286 | common::LanguageFeatureControl features; |
287 | |
288 | // Source file encoding |
289 | Fortran::parser::Encoding encoding{Fortran::parser::Encoding::UTF_8}; |
290 | |
291 | /// The list of plugins to load. |
292 | std::vector<std::string> plugins; |
293 | |
294 | /// The name of the action to run when using a plugin action. |
295 | std::string actionName; |
296 | |
297 | /// A list of arguments to forward to LLVM's option processing; this |
298 | /// should only be used for debugging and experimental features. |
299 | std::vector<std::string> llvmArgs; |
300 | |
301 | /// A list of arguments to forward to MLIR's option processing; this |
302 | /// should only be used for debugging and experimental features. |
303 | std::vector<std::string> mlirArgs; |
304 | |
305 | // Return the appropriate input kind for a file extension. For example, |
306 | /// "*.f" would return Language::Fortran. |
307 | /// |
308 | /// \return The input kind for the extension, or Language::Unknown if the |
309 | /// extension is not recognized. |
310 | static InputKind getInputKindForExtension(llvm::StringRef extension); |
311 | }; |
312 | } // namespace Fortran::frontend |
313 | |
314 | #endif // FORTRAN_FRONTEND_FRONTENDOPTIONS_H |
315 |
Warning: This file is not a C or C++ file. It does not have highlighting.