1 <!--===- docs/FlangDriver.md
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
17 > **_NOTE:_** This document assumes that Flang's drivers can already generate code and
18 > produce executables. However, this is still work-in-progress. By making this
19 > assumption, we are able to prepare this document ahead-of-time and to provide
20 > an overview of the design that we are working towards.
22 There are two main drivers in Flang:
23 * the compiler driver, `flang-new`
24 * the frontend driver, `flang-new -fc1`
26 > **_NOTE:_** The diagrams in this document refer to `flang` as opposed to
27 > `flang-new`. This is because the diagrams reflect the final design that we
28 > are still working towards. See the note on [the flang script](https://github.com/llvm/llvm-project/blob/main/flang/docs/FlangDriver.md#the-flang-script)
29 > below for more context.
31 The **compiler driver** will allow you to control all compilation phases (e.g.
32 preprocessing, semantic checks, code-generation, code-optimisation, lowering
33 and linking). For frontend specific tasks, the compiler driver creates a
34 Fortran compilation job and delegates it to `flang-new -fc1`, the frontend
35 driver. For linking, it creates a linker job and calls an external linker (e.g.
36 LLVM's [`lld`](https://lld.llvm.org/)). It can also call other tools such as
37 external assemblers (e.g. [`as`](https://www.gnu.org/software/binutils/)). In
38 Clang, the compiler driver can also link the generated binaries with LLVM's
39 static analysis/sanitizer libraries (e.g.
40 [MemorySanitizer](https://clang.llvm.org/docs/MemorySanitizer.html)). This is
41 not yet available in Flang, but will be relatively easy to support once such
42 libraries become available. Flang's compiler driver is intended for Flang's
43 end-users - its interface needs to remain stable. Otherwise, Flang's users will
44 have to adjust their build scripts every time a compiler flag is changed.
46 | ![Compiler Driver](compiler_driver.png) |
48 | *Flang’s compiler driver and the **tools** that it runs* |
50 The **frontend driver** glues together and drives all of the Flang's frontend
51 libraries. As such, it provides an easy-to-use and intuitive interface to the
52 frontend. It uses MLIR and LLVM for code-generation and can be viewed as a
53 driver for Flang, LLVM and MLIR libraries. Contrary to the compiler driver, it
54 is not capable of calling any external tools (including linkers). It is aware
55 of all the frontend internals that are "hidden" from the compiler driver. It
56 accepts many frontend-specific options not available in `flang-new` and as such
57 it provides a finer control over the frontend. Note that this tool is mostly
58 intended for Flang developers. In particular, there are no guarantees about the
59 stability of its interface and compiler developers can use it to experiment
62 | ![Frontend Driver](frontend_driver.png) |
64 | *Flang's frontend driver and the **libraries** that it drives* |
66 Note that similarly to `-Xclang` in `clang`, you can use `-Xflang` to forward a
67 frontend specific flag from the _compiler_ directly to the _frontend_ driver,
71 flang-new -Xflang -fdebug-dump-parse-tree input.f95
74 In the invocation above, `-fdebug-dump-parse-tree` is forwarded to `flang-new
75 -fc1`. Without the forwarding flag, `-Xflang`, you would see the following
79 flang-new: warning: argument unused during compilation:
82 As `-fdebug-dump-parse-tree` is only supported by `flang-new -fc1`, `flang-new`
83 will ignore it when used without `Xflang`.
85 ## Why Do We Need Two Drivers?
86 As hinted above, `flang-new` and `flang-new -fc1` are two separate tools. The
87 fact that these tools are accessed through one binary, `flang-new`, is just an
88 implementation detail. Each tool has a separate list of options, albeit defined
89 in the same file: `clang/include/clang/Driver/Options.td`.
91 The separation helps us split various tasks and allows us to implement more
92 specialised tools. In particular, `flang-new` is not aware of various
93 compilation phases within the frontend (e.g. scanning, parsing or semantic
94 checks). It does not have to be. Conversely, the frontend driver, `flang-new
95 -fc1`, needs not to be concerned with linkers or other external tools like
96 assemblers. Nor does it need to know where to look for various systems
97 libraries, which is usually OS and platform specific.
99 One helpful way of differentiating these tools is to keep in mind that:
101 * the compiler driver is an end-user tool
102 * frontend driver is a compiler developer tool with many additional options,
104 Also, Since the compiler driver can call external tools, e.g. linkers, it can
105 be used to generate **executables**. The frontend driver cannot call external
106 tools and hence can only generate **object files**. A similar model is
107 implemented in Clang (`clang` vs `clang -cc1` vs `clang -cc1as`), which is
108 based on the [architecture of
109 GCC](https://en.wikibooks.org/wiki/GNU_C_Compiler_Internals/GNU_C_Compiler_Architecture).
110 In fact, Flang needs to adhere to this model in order to be able to re-use
111 Clang's driver library. If you are more familiar with the [architecture of
112 GFortran](https://gcc.gnu.org/onlinedocs/gcc-4.7.4/gfortran/About-GNU-Fortran.html)
113 than Clang, then `flang-new` corresponds to `gfortran` and `flang-new -fc1` to
117 The main entry point for Flang's compiler driver is implemented in
118 `flang/tools/flang-driver/driver.cpp`. Flang's compiler driver is implemented
119 in terms of Clang's driver library, `clangDriver`. This approach allows us to:
120 * benefit from Clang's support for various targets, platforms and operating systems
121 * leverage Clang's ability to drive various backends available in LLVM, as well
122 as linkers and assemblers.
123 One implication of this dependency on Clang is that all of Flang's compiler
124 options are defined alongside Clang's options in
125 `clang/include/clang/Driver/Options.td`. For options that are common for both
126 Flang and Clang, the corresponding definitions are shared.
128 Internally, a `clangDriver` based compiler driver works by creating actions
129 that correspond to various compilation phases, e.g. `PreprocessJobClass`,
130 `CompileJobClass`, `BackendJobClass` or `LinkJobClass` from the
131 `clang::driver::Action::ActionClass` enum. There are also other, more
132 specialised actions, e.g. `MigrateJobClass` or `InputClass`, that do not map
133 directly to common compilation steps. The actions to run are determined from
134 the supplied compiler flags, e.g.
136 * `-E` for `PreprocessJobClass`,
137 * `-c` for `CompileJobClass`.
139 In most cases, the driver creates a chain of actions/jobs/phases where the
140 output from one action is the input for the subsequent one. You can use the
141 `-ccc-print-phases` flag to see the sequence of actions that the driver will
142 create for your compiler invocation:
144 flang-new -ccc-print-phases -E file.f
145 +- 0: input, "file.f", f95-cpp-input
146 1: preprocessor, {0}, f95
148 As you can see, for `-E` the driver creates only two jobs and stops immediately
149 after preprocessing. The first job simply prepares the input. For `-c`, the
150 pipeline of the created jobs is more complex:
152 flang-new -ccc-print-phases -c file.f
153 +- 0: input, "file.f", f95-cpp-input
154 +- 1: preprocessor, {0}, f95
155 +- 2: compiler, {1}, ir
156 +- 3: backend, {2}, assembler
157 4: assembler, {3}, object
159 Note that currently Flang does not support code-generation and `flang-new` will
160 fail during the second step above with the following error:
162 error: code-generation is not available yet
164 The other phases are printed nonetheless when using `-ccc-print-phases`, as
165 that reflects what `clangDriver`, the library, will try to create and run.
167 For actions specific to the frontend (e.g. preprocessing or code generation), a
168 command to call the frontend driver is generated (more specifically, an
169 instance of `clang::driver::Command`). Every command is bound to an instance of
170 `clang::driver::Tool`. For Flang we introduced a specialisation of this class:
171 `clang::driver::Flang`. This class implements the logic to either translate or
172 forward compiler options to the frontend driver, `flang-new -fc1`.
174 You can read more on the design of `clangDriver` in Clang's [Driver Design &
175 Internals](https://clang.llvm.org/docs/DriverInternals.html).
178 Flang's frontend driver is the main interface between compiler developers and
179 the Flang frontend. The high-level design is similar to Clang's frontend
180 driver, `clang -cc1` and consists of the following classes:
181 * `CompilerInstance`, which is a helper class that encapsulates and manages
182 various objects that are always required by the frontend (e.g. `AllSources`,
183 `AllCookedSources, `Parsing`, `CompilerInvocation`, etc.). In most cases
184 `CompilerInstance` owns these objects, but it also can share them with its
185 clients when required. It also implements utility methods to construct and
187 * `CompilerInvocation` encapsulates the configuration of the current
188 invocation of the compiler as derived from the command-line options and the
189 input files (in particular, file extensions). Among other things, it holds an
190 instance of `FrontendOptions`. Like `CompilerInstance`, it owns the objects
191 that it manages. It can share them with its clients that want to access them
192 even after the corresponding `CompilerInvocation` has been destructed.
193 * `FrontendOptions` holds options that control the behaviour of the frontend,
194 as well as e.g. the list of the input files. These options come either
195 directly from the users (through command-line flags) or are derived from
196 e.g. the host system configuration.
197 * `FrontendAction` and `FrontendActions` (the former being the base class for
198 the latter) implement the actual actions to perform by the frontend. Usually
199 there is one specialisation of `FrontendActions` for every compiler action flag
200 (e.g. `-E`, `-fdebug-unparse`). These classes also contain various hooks that
201 allow you to e.g. fine-tune the configuration of the frontend based on the
204 This list is not exhaustive and only covers the main classes that implement the
205 driver. The main entry point for the frontend driver, `fc1_main`, is
206 implemented in `flang/tools/flang-driver/driver.cpp`. It can be accessed by
207 invoking the compiler driver, `flang-new`, with the `-fc1` flag.
209 The frontend driver will only run one action at a time. If you specify multiple
210 action flags, only the last one will be taken into account. The default action
211 is `ParseSyntaxOnlyAction`, which corresponds to `-fsyntax-only`. In other
212 words, `flang-new -fc1 <input-file>` is equivalent to `flang-new -fc1 -fsyntax-only
215 ## The `flang` script
216 The `flang` wrapper script for `flang-new` was introduced as a development tool
217 and to facilitate testing. While code-generation is not available in Flang, you
218 can use it as a drop-in replacement for other Fortran compilers in your build
221 The `flang` wrapper script will:
222 * use `flang-new` to unparse the input source file (i.e. it will run `flang-new
223 -fc1 -fdebug-unparse <input-file>`), and then
224 * call a host Fortran compiler, e.g. `gfortran`, to compile the unparsed file.
226 Here's a basic breakdown of what happens inside `flang` when you run `flang
229 flang-new -fc1 -fdebug-unparse file.f90 -o file-unparsed.f90
230 gfortran file-unparsed.f90
232 This is a simplified version for illustration purposes only. In practice,
233 `flang` adds a few more frontend options and it also supports various other use
234 cases (e.g. compiling C files, linking existing object files). `gfortran` is
235 the default host compiler used by `flang`. You can change it by setting the
236 `FLANG_FC` environment variable.
238 Our intention is to replace `flang` with `flang-new`. Please consider `flang`
239 as a temporary substitute for Flang's compiler driver while the actual driver
242 ## Adding new Compiler Options
243 Adding a new compiler option in Flang consists of two steps:
244 * define the new option in a dedicated TableGen file,
245 * parse and implement the option in the relevant drivers that support it.
247 ### Option Definition
248 All of Flang's compiler and frontend driver options are defined in
249 `clang/include/clang/Driver/Options.td` in Clang. When adding a new option to
250 Flang, you will either:
251 * extend the existing definition for an option that is already available
252 in one of Clang's drivers (e.g. `clang`), but not yet available in Flang, or
253 * add a completely new definition if the option that you are adding has not
256 There are many predefined TableGen classes and records that you can use to fine
257 tune your new option. The list of available configurations can be overwhelming
258 at times. Sometimes the easiest approach is to find an existing option that has
259 similar semantics to your new option and start by copying that.
261 For every new option, you will also have to define the visibility of the new
262 option. This is controlled through the `Flags` field. You can use the following
263 Flang specific option flags to control this:
264 * `FlangOption` - this option will be available in the `flang-new` compiler driver,
265 * `FC1Option` - this option will be available in the `flang-new -fc1` frontend driver,
266 * `FlangOnlyOption` - this option will not be visible in Clang drivers.
268 Please make sure that options that you add are only visible in drivers that can
269 support it. For example, options that only make sense for Fortran input files
270 (e.g. `-ffree-form`) should not be visible in Clang and be marked as
273 When deciding what `OptionGroup` to use when defining a new option in the
274 `Options.td` file, many new options fall into one of the following two
276 * `Action_Group` - options that define an action to run (e.g.
277 `-fsyntax-only`, `-E`)
278 * `f_Group` - target independent compiler flags (e.g. `-ffixed-form`,
280 There are also other groups and occasionally you will use them instead of the
283 ### Option Implementation
284 First, every option needs to be parsed. Flang compiler options are parsed in
285 two different places, depending on which driver they belong to:
287 * frontend driver: `flang/lib/Frontend/CompilerInvocation.cpp`,
288 * compiler driver: `clang/lib/Driver/ToolChains/Flang.cpp`.
290 The parsing will depend on the semantics encoded in the TableGen definition.
292 When adding a compiler driver option (i.e. an option that contains
293 `FlangOption` among its `Flags`) that you also intend to be understood by the
294 frontend, make sure that it is either forwarded to `flang-new -fc1` or translated
295 into some other option that is accepted by the frontend driver. In the case of
296 options that contain both `FlangOption` and `FC1Option` among its flags, we
297 usually just forward from `flang-new` to `flang-new -fc1`. This is then tested in
298 `flang/test/Driver/frontend-forward.F90`.
300 What follows is usually very dependant on the meaning of the corresponding
301 option. In general, regular compiler flags (e.g. `-ffree-form`) are mapped to
302 some state within the driver. A lot of this state is stored within an instance
303 of `FrontendOptions`, but there are other more specialised classes too. Action
304 flags (e.g. `-fsyntax-only`) are usually more complex overall, but also more
305 structured in terms of the implementation.
308 For options that correspond to an action (i.e. marked as `Action_Group`), you
309 will have to define a dedicated instance of `FrontendActions` in
310 `flang/include/flang/Frontend/FrontendOptions.h`. For example, for
311 `-fsyntax-only` we defined:
313 class ParseSyntaxOnlyAction : public PrescanAndSemaAction {
314 void ExecuteAction() override;
317 Command line options are mapped to frontend actions through the
318 `Fortran::frontend::ActionKind` enum. For every new action option that you
319 add, you will have to add a dedicated entry in that enum (e.g.
320 `ParseSyntaxOnly` for `-fsyntax-only`) and a corresponding `case` in
321 `ParseFrontendArgs` function in the `CompilerInvocation.cpp` file, e.g.:
323 case clang::driver::options::OPT_fsyntax_only:
324 opts.programAction = ParseSyntaxOnly;
327 Note that this simply sets the program/frontend action within the frontend
328 driver. You still have make sure that the corresponding frontend action class
329 is instantiated when your new action option is used. The relevant `switch`
330 statement is implemented in `Fortran::frontend::CreatedFrontendBaseAction` in
331 the `ExecuteCompilerInvocation.cpp` file. Here's an example for
334 case ParseSyntaxOnly:
335 return std::make_unique<ParseSyntaxOnlyAction>();
337 At this point you should be able to trigger that frontend action that you have
338 just added using your new frontend option.
341 In LIT, we define two variables that you can use to invoke Flang's drivers:
342 * `%flang` is expanded as `flang-new` (i.e. the compiler driver)
343 * `%flang_fc1` is expanded as `flang-new -fc1` (i.e. the frontend driver)
345 For most regression tests for the frontend, you will want to use `%flang_fc1`.
346 In some cases, the observable behaviour will be identical regardless of whether
347 `%flang` or `%flang_fc1` is used. However, when you are using `%flang` instead
348 of `%flang_fc1`, the compiler driver will add extra flags to the frontend
349 driver invocation (i.e. `flang-new -fc1 -<extra-flags>`). In some cases that might
350 be exactly what you want to test. In fact, you can check these additional
351 flags by using the `-###` compiler driver command line option.
353 Lastly, you can use `! REQUIRES: <feature>` for tests that will only work when
354 `<feature>` is available. For example, you can use`! REQUIRES: shell` to mark a
355 test as only available on Unix-like systems (i.e. systems that contain a Unix
356 shell). In practice this means that the corresponding test is skipped on
359 # Frontend Driver Plugins
360 Plugins are an extension to the frontend driver that make it possible to run
361 extra user defined frontend actions, in the form of a specialization of a
362 `PluginParseTreeAction`. These actions are run during compilation, after
363 semantic checks. Similarly to Clang, Flang leverages `LoadLibraryPermanently`
364 from LLVM's `llvm::sys::DynamicLibrary` to load dynamic objects that implement
365 plugins. The process for using plugins includes:
366 * [Creating a plugin](#creating-a-plugin)
367 * [Loading and running a plugin](#loading-and-running-a-plugin)
369 Flang plugins are limited to `flang-new -fc1` and are currently only available /
370 been tested on Linux.
373 There are three parts required for plugins to work:
374 1. [`PluginParseTreeAction` subclass](#a-pluginparsetreeaction-subclass)
375 1. [Implementation of `ExecuteAction`](#implementation-of-executeaction)
376 1. [Plugin registration](#plugin-registration)
378 There is an example plugin located in `flang/example/PrintFlangFunctionNames`
379 that demonstrates these points by using the `ParseTree` API to print out
380 function and subroutine names declared in the input file.
382 ### A `PluginParseTreeAction` Subclass
383 This subclass will wrap everything together and represent the `FrontendAction`
384 corresponding to your plugin. It will need to inherit from
385 `PluginParseTreeAction` (defined in `flang/include/flang/FrontendActions.h`), in
386 order to have access to the parse tree post semantic checks, and also so that it
387 can be registered, e.g.
389 class PrintFunctionNamesAction : public PluginParseTreeAction
392 ### Implementation of `ExecuteAction`
393 Like in other frontend actions, the driver looks for an `ExecuteAction` function
394 to run, so in order for your plugin to do something, you will need to implement
395 the `ExecuteAction` method in your plugin class. This method will contain the
396 implementation of what the plugin actually does, for example:
398 void ExecuteAction() override {
399 auto &parseTree{instance().parsing().parseTree()};
400 ParseTreeVisitor visitor;
401 Fortran::parser::Walk(parseTree, visitor);
404 In the example plugin, the `ExecuteAction` method first gets a reference to the
405 parse tree, `instance().parsing().parseTree()`, then declares a `visitor`
406 struct, before passing both of these to the `Fortran::parser::Walk` function
407 that will traverse the parse tree. Implementation and details of the `Walk`
408 function can be found in `flang/include/flang/Parser/parse-tree-visitor.h`.
410 A `visitor` struct should define different `Pre` and `Post` functions that take
411 the type of a specific `ParseTree` node as an argument. When the `Walk` function
412 is traversing the parse tree, these functions will be run before/after a node
413 of that type is visited. Template functions for `Pre`/`Post` are defined so that
414 when a node is visited that you have not defined a function for, it will still
415 be able to continue. `Pre` returns a `bool` indicating whether to visit that
416 node's children or not. For example:
418 struct ParseTreeVisitor {
419 template <typename A> bool Pre(const A&) { return true; }
420 template <typename A> void Post(const A&) {}
421 void Post(const Fortran::parser::FunctionStmt &f) {
422 llvm::outs() << std::get<Fortran::parser::Name>(f.t).ToString() << "\n" ;
426 The different types of nodes and also what each node structure contains are
427 defined in `flang/include/flang/Parser/parse-tree.h`. In the example, there is a
428 `Post` function, with a line that gets the `Name` element from a tuple `t` in
429 the `FunctionStmt` struct and prints it. This function will be run after every
430 `FunctionStmt` node is visited in the parse tree.
432 ### Plugin Registration
433 A plugin registry is used to store names and descriptions of a collection of
434 plugins. The Flang plugin registry, defined in
435 `flang/include/flang/Frontend/FrontendPluginRegistry.h`, is an alias of
436 `llvm::Registry` of type `PluginParseTreeAction`.
438 The plugin will need to be registered, which will add the Plugin to the registry
439 and allow it to be used. The format is as follows, with `print-fns` being the
440 plugin name that is used later to call the plugin and `Print Function names`
441 being the description:
443 static FrontendPluginRegistry::Add<PrintFunctionNamesAction> X(
444 "print-fns", "Print Function names");
447 ## Loading and Running a Plugin
448 In order to use plugins, there are 2 command line options made available to the
449 frontend driver, `flang-new -fc1`:
450 * [`-load <dsopath>`](#the--load-dsopath-option) for loading the dynamic shared
452 * [`-plugin <name>`](#the--plugin-name-option) for calling the registered plugin
454 Invocation of the example plugin is done through:
456 flang-new -fc1 -load flangPrintFunctionNames.so -plugin print-fns file.f90
459 Both these options are parsed in `flang/lib/Frontend/CompilerInvocation.cpp` and
460 fulfil their actions in
461 `flang/lib/FrontendTool/ExecuteCompilerInvocation.cpp`
463 ### The `-load <dsopath>` option
464 This loads the plugin shared object library, with the path given at `<dsopath>`,
465 using `LoadLibraryPermantly` from LLVM's `llvm::sys::DynamicLibrary`, which
466 itself uses `dlopen`. During this stage, the plugin is registered with the
467 registration line from the plugin, storing the name and description.
469 ### The `-plugin <name>` option
470 This sets `frontend::ActionKind programAction` in `FrontendOptions` to
471 `PluginAction`, through which it searches the plugin registry for the plugin
472 name from `<name>`. If found, it returns the instantiated plugin, otherwise it
473 reports an error diagnostic and returns `nullptr`.
475 ## Enabling In-Tree Plugins
476 For in-tree plugins, there is the CMake flag `FLANG_PLUGIN_SUPPORT`, enabled by
477 default, that controls the exporting of executable symbols from `flang-new`,
478 which plugins need access to. Additionally, there is the CMake flag
479 `FLANG_BUILD_EXAMPLES`, turned off by default, that is used to control if the
480 example programs are built. This includes plugins that are in the
481 `flang/example` directory and added as a `sub_directory` to the
482 `flang/examples/CMakeLists.txt`, for example, the `PrintFlangFunctionNames`
483 plugin. It is also possible to develop plugins out-of-tree.
486 Note that the traversal API presented here is under active development and
487 might change in the future. We expect it to evolve as support for new
488 language features are added. This document and the examples will be updated
491 The current `ParseTree` structure is not suitable for modifications. The
492 copy constructors are not available and hence duplicating code might not be
493 trivial. Please take this into consideration when designing your plugin. In
494 particular, creating a transformation plugin will be noticeably harder than
495 analysis plugins that just consume (rather than edit) `ParseTree`.
497 Lastly, if `ParseTree` modifications are performed, then it might be necessary
498 to re-analyze expressions and modify scope or symbols. You can check
499 [Semantics.md](Semantics.md) for more details on how `ParseTree` is edited
500 e.g. during the semantic checks.