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