xref: /llvm-project/flang/include/flang/Frontend/FrontendAction.h (revision f2e808932ceddf503897d0b5c75bc22fb3262349)
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 &currentIntput);
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