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