| //===- FrontendOptions.h ----------------------------------------*- C++ -*-===// |
| // |
| // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. |
| // See https://llvm.org/LICENSE.txt for license information. |
| // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception |
| // |
| //===----------------------------------------------------------------------===// |
| #ifndef LLVM_FLANG_FRONTEND_FRONTENDOPTIONS_H |
| #define LLVM_FLANG_FRONTEND_FRONTENDOPTIONS_H |
| |
| #include "llvm/ADT/StringRef.h" |
| #include "llvm/Support/MemoryBuffer.h" |
| |
| #include <cstdint> |
| #include <string> |
| |
| namespace Fortran::frontend { |
| |
| enum ActionKind { |
| InvalidAction = 0, |
| |
| /// -test-io mode |
| InputOutputTest, |
| |
| /// -E mode. |
| PrintPreprocessedInput, |
| |
| /// -fsyntax-only |
| ParseSyntaxOnly, |
| |
| /// Emit a .o file. |
| EmitObj, |
| |
| /// TODO: RunPreprocessor, EmitLLVM, EmitLLVMOnly, |
| /// EmitCodeGenOnly, EmitAssembly, (...) |
| }; |
| |
| /// \param suffix The file extension |
| /// \return True if the file extension should be processed as fixed form |
| bool isFixedFormSuffix(llvm::StringRef suffix); |
| |
| /// \param suffix The file extension |
| /// \return True if the file extension should be processed as free form |
| bool isFreeFormSuffix(llvm::StringRef suffix); |
| |
| inline const char *GetActionKindName(const ActionKind ak) { |
| switch (ak) { |
| case InputOutputTest: |
| return "InputOutputTest"; |
| case PrintPreprocessedInput: |
| return "PrintPreprocessedInput"; |
| case ParseSyntaxOnly: |
| return "ParseSyntaxOnly"; |
| default: |
| return "<unknown ActionKind>"; |
| // TODO: |
| // case RunPreprocessor: |
| // case ParserSyntaxOnly: |
| // case EmitLLVM: |
| // case EmitLLVMOnly: |
| // case EmitCodeGenOnly: |
| // (...) |
| } |
| } |
| |
| enum class Language : uint8_t { |
| Unknown, |
| |
| /// LLVM IR: we accept this so that we can run the optimizer on it, |
| /// and compile it to assembly or object code. |
| LLVM_IR, |
| |
| /// @{ Languages that the frontend can parse and compile. |
| Fortran, |
| }; |
| |
| /// The kind of a file that we've been handed as an input. |
| class InputKind { |
| private: |
| Language lang_; |
| |
| public: |
| /// The input file format. |
| enum Format { Source, ModuleMap, Precompiled }; |
| |
| constexpr InputKind(Language l = Language::Unknown) : lang_(l) {} |
| |
| Language GetLanguage() const { return static_cast<Language>(lang_); } |
| |
| /// Is the input kind fully-unknown? |
| bool IsUnknown() const { return lang_ == Language::Unknown; } |
| }; |
| |
| /// An input file for the front end. |
| class FrontendInputFile { |
| /// The file name, or "-" to read from standard input. |
| std::string file_; |
| |
| /// The input, if it comes from a buffer rather than a file. This object |
| /// does not own the buffer, and the caller is responsible for ensuring |
| /// that it outlives any users. |
| const llvm::MemoryBuffer *buffer_ = nullptr; |
| |
| /// The kind of input, atm it contains language |
| InputKind kind_; |
| |
| /// Is this input file in fixed-form format? This is simply derived from the |
| /// file extension and should not be altered by consumers. For input from |
| /// stdin this is never modified. |
| bool isFixedForm_ = false; |
| |
| public: |
| FrontendInputFile() = default; |
| FrontendInputFile(llvm::StringRef file, InputKind kind) |
| : file_(file.str()), kind_(kind) { |
| |
| // Based on the extension, decide whether this is a fixed or free form |
| // file. |
| auto pathDotIndex{file.rfind(".")}; |
| std::string pathSuffix{file.substr(pathDotIndex + 1)}; |
| isFixedForm_ = isFixedFormSuffix(pathSuffix); |
| } |
| FrontendInputFile(const llvm::MemoryBuffer *buffer, InputKind kind) |
| : buffer_(buffer), kind_(kind) {} |
| |
| InputKind kind() const { return kind_; } |
| |
| bool IsEmpty() const { return file_.empty() && buffer_ == nullptr; } |
| bool IsFile() const { return !IsBuffer(); } |
| bool IsBuffer() const { return buffer_ != nullptr; } |
| bool IsFixedForm() const { return isFixedForm_; } |
| |
| llvm::StringRef file() const { |
| assert(IsFile()); |
| return file_; |
| } |
| |
| const llvm::MemoryBuffer *buffer() const { |
| assert(IsBuffer() && "Requested buffer_, but it is empty!"); |
| return buffer_; |
| } |
| }; |
| |
| /// FrontendOptions - Options for controlling the behavior of the frontend. |
| class FrontendOptions { |
| public: |
| /// Show the -help text. |
| unsigned showHelp_ : 1; |
| |
| /// Show the -version text. |
| unsigned showVersion_ : 1; |
| |
| /// The input files and their types. |
| std::vector<FrontendInputFile> inputs_; |
| |
| /// The output file, if any. |
| std::string outputFile_; |
| |
| /// The frontend action to perform. |
| frontend::ActionKind programAction_; |
| |
| public: |
| FrontendOptions() : showHelp_(false), showVersion_(false) {} |
| |
| // Return the appropriate input kind for a file extension. For example, |
| /// "*.f" would return Language::Fortran. |
| /// |
| /// \return The input kind for the extension, or Language::Unknown if the |
| /// extension is not recognized. |
| static InputKind GetInputKindForExtension(llvm::StringRef extension); |
| }; |
| } // namespace Fortran::frontend |
| |
| #endif // LLVM_FLANG_FRONTEND_FRONTENDOPTIONS_H |