1 //===- FrontendAction.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 /// \file 10 /// Defines the flang::FrontendAction interface. 11 /// 12 //===----------------------------------------------------------------------===// 13 // 14 // Coding style: https://mlir.llvm.org/getting_started/DeveloperGuide/ 15 // 16 //===----------------------------------------------------------------------===// 17 18 #ifndef FORTRAN_FRONTEND_FRONTENDACTION_H 19 #define FORTRAN_FRONTEND_FRONTENDACTION_H 20 21 #include "flang/Frontend/FrontendOptions.h" 22 #include "llvm/Support/Error.h" 23 24 namespace Fortran::frontend { 25 class CompilerInstance; 26 27 /// Abstract base class for actions which can be performed by the frontend. 28 class FrontendAction { 29 FrontendInputFile currentInput; 30 CompilerInstance *instance; 31 32 protected: 33 /// @name Implementation Action Interface 34 /// @{ 35 36 /// Callback to run the program action, using the initialized 37 /// compiler instance. 38 virtual void executeAction() = 0; 39 40 /// Callback at the end of processing a single input, to determine 41 /// if the output files should be erased or not. 42 /// 43 /// By default it returns true if a compiler error occurred. 44 virtual bool shouldEraseOutputFiles(); 45 46 /// Callback at the start of processing a single input. 47 /// 48 /// \return True on success; on failure ExecutionAction() and 49 /// EndSourceFileAction() will not be called. beginSourceFileAction()50 virtual bool beginSourceFileAction() { return true; } 51 52 /// @} 53 54 public: FrontendAction()55 FrontendAction() : instance(nullptr) {} 56 virtual ~FrontendAction() = default; 57 58 /// @name Compiler Instance Access 59 /// @{ 60 getInstance()61 CompilerInstance &getInstance() const { 62 assert(instance && "Compiler instance not registered!"); 63 return *instance; 64 } 65 setInstance(CompilerInstance * value)66 void setInstance(CompilerInstance *value) { instance = value; } 67 68 /// @} 69 /// @name Current File Information 70 /// @{ 71 getCurrentInput()72 const FrontendInputFile &getCurrentInput() const { return currentInput; } 73 getCurrentFile()74 llvm::StringRef getCurrentFile() const { 75 assert(!currentInput.isEmpty() && "No current file!"); 76 return currentInput.getFile(); 77 } 78 getCurrentFileOrBufferName()79 llvm::StringRef getCurrentFileOrBufferName() const { 80 assert(!currentInput.isEmpty() && "No current file!"); 81 return currentInput.isFile() 82 ? currentInput.getFile() 83 : currentInput.getBuffer()->getBufferIdentifier(); 84 } 85 void setCurrentInput(const FrontendInputFile ¤tIntput); 86 87 /// @} 88 /// @name Public Action Interface 89 /// @{ 90 91 /// Prepare the action for processing the input file \p input. 92 /// 93 /// This is run after the options and frontend have been initialized, 94 /// but prior to executing any per-file processing. 95 /// \param ci - The compiler instance this action is being run from. The 96 /// action may store and use this object. 97 /// \param input - The input filename and kind. 98 /// \return True on success; on failure the compilation of this file should 99 bool beginSourceFile(CompilerInstance &ci, const FrontendInputFile &input); 100 101 /// Run the action. 102 llvm::Error execute(); 103 104 /// Perform any per-file post processing, deallocate per-file 105 /// objects, and run statistics and output file cleanup code. 106 void endSourceFile(); 107 108 /// @} 109 protected: 110 // Prescan the current input file. Return False if fatal errors are reported, 111 // True otherwise. 112 bool runPrescan(); 113 // Parse the current input file. Return False if fatal errors are reported, 114 // True otherwise. 115 bool runParse(bool emitMessages); 116 // Run semantic checks for the current input file. Return False if fatal 117 // errors are reported, True otherwise. 118 bool runSemanticChecks(); 119 // Generate run-time type information for derived types. This may lead to new 120 // semantic errors. Return False if fatal errors are reported, True 121 // otherwise. 122 bool generateRtTypeTables(); 123 124 // Report fatal semantic errors. Return True if present, false otherwise. 125 bool reportFatalSemanticErrors(); 126 127 // Report fatal scanning errors. Return True if present, false otherwise. reportFatalScanningErrors()128 inline bool reportFatalScanningErrors() { 129 return reportFatalErrors("Could not scan %0"); 130 } 131 132 // Report fatal parsing errors. Return True if present, false otherwise reportFatalParsingErrors()133 inline bool reportFatalParsingErrors() { 134 return reportFatalErrors("Could not parse %0"); 135 } 136 137 private: 138 template <unsigned N> 139 bool reportFatalErrors(const char (&message)[N]); 140 }; 141 142 } // namespace Fortran::frontend 143 144 #endif // FORTRAN_FRONTEND_FRONTENDACTION_H 145