diff --git a/flang/docs/ArrayComposition.md b/flang/docs/ArrayComposition.md --- a/flang/docs/ArrayComposition.md +++ b/flang/docs/ArrayComposition.md @@ -6,6 +6,13 @@ --> +# Array Composition + +```eval_rst +.. contents:: + :local: +``` + This note attempts to describe the motivation for and design of an implementation of Fortran 90 (and later) array expression evaluation that minimizes the use of dynamically allocated temporary storage for @@ -34,8 +41,8 @@ `COMMAND_ARGUMENT_COUNT`) but not of interest for this note. The generic `REDUCE` is also not considered here. -Arrays as functions -=================== +## Arrays as functions + A whole array can be viewed as a function that maps its indices to the values of its elements. Specifically, it is a map from a tuple of integers to its element type. @@ -45,8 +52,8 @@ `REAL :: A(N,M)` can be seen as a function mapping ordered pairs of integers `(J,K)` with `1<=J<=N` and `1<=J<=M` to real values. -Array expressions as functions -============================== +## Array expressions as functions + The same perspective can be taken of an array expression comprising intrinsic operators and elemental functions. Fortran doesn't allow one to apply subscripts directly to an expression, @@ -83,8 +90,8 @@ function calls on the right-hand side are elemental or scalar-valued, we can avoid the use of a temporary. -Transformational intrinsic functions as function composition -============================================================ +## Transformational intrinsic functions as function composition + Many of the transformational intrinsic functions listed above can, when their array arguments are viewed as functions over their index tuples, be seen as compositions of those functions with @@ -127,8 +134,8 @@ * `SPREAD(A,DIM=d,NCOPIES=n)` for compile-time `d` simply applies `A` to a reduced index tuple. -Determination of rank and shape -=============================== +## Determination of rank and shape + An important part of evaluating array expressions without the use of temporary storage is determining the shape of the result prior to, or without, evaluating the elements of the result. @@ -173,8 +180,8 @@ be able to have the opportunity to avoid heap allocation in favor of stack storage, if the scope of the variable is local. -Automatic reallocation of allocatables -====================================== +## Automatic reallocation of allocatables + Fortran 2003 introduced the ability to assign non-conforming array expressions to ALLOCATABLE arrays with the implied semantics of reallocation to the new shape. @@ -182,8 +189,8 @@ our implementation of array expressions has decoupled calculation of shapes from the evaluation of the elements of the result. -Rewriting rules -=============== +## Rewriting rules + Let `{...}` denote an ordered tuple of 1-based indices, e.g. `{j,k}`, into the result of an array expression or subexpression. diff --git a/flang/docs/BijectiveInternalNameUniquing.md b/flang/docs/BijectiveInternalNameUniquing.md --- a/flang/docs/BijectiveInternalNameUniquing.md +++ b/flang/docs/BijectiveInternalNameUniquing.md @@ -1,4 +1,9 @@ -## Bijective Internal Name Uniquing +# Bijective Internal Name Uniquing + +```eval_rst +.. contents:: + :local: +``` FIR has a flat namespace. No two objects may have the same name at the module level. (These would be functions, globals, etc.) @@ -13,14 +18,14 @@ user's identifiers to all lower case. Such a universal conversion implies that all upper case letters are available for use in uniquing. -### Prefix `_Q` +## Prefix `_Q` All uniqued names have the prefix sequence `_Q` to indicate the name has been uniqued. (Q is chosen because it is a [low frequency letter](http://pi.math.cornell.edu/~mec/2003-2004/cryptography/subs/frequencies.html) in English.) -### Scope Building +## Scope Building Symbols can be scoped by the module, submodule, or procedure that contains that symbol. After the `_Q` sigil, names are constructed from outermost to @@ -45,7 +50,7 @@ _QMmodSs1modSs2modFsubPfun ``` -### Common blocks +## Common blocks * A common block name will be prefixed with `B` @@ -69,7 +74,7 @@ _QB ``` -### Module scope global data +## Module scope global data * A global data entity is prefixed with `E` * A global entity that is constant (parameter) will be prefixed with `EC` @@ -92,7 +97,7 @@ _QMmodECpi ``` -### Procedures/Subprograms +## Procedures/Subprograms * A procedure/subprogram is prefixed with `P` @@ -105,7 +110,7 @@ _QPsub ``` -### Derived types and related +## Derived types and related * A derived type is prefixed with `T` * If a derived type has KIND parameters, they are listed in a consistent @@ -148,7 +153,7 @@ type `yourtype` above would be `_QCTyourtypeK4KN6`. The type descriptor for `REAL(4)` would be `_QCrealK4`. -### Compiler generated names +## Compiler generated names Compiler generated names do not have to be mapped back to Fortran. These names will be prefixed with `_QQ` and followed by a unique compiler diff --git a/flang/docs/C++17.md b/flang/docs/C++17.md --- a/flang/docs/C++17.md +++ b/flang/docs/C++17.md @@ -6,7 +6,12 @@ --> -## C++14/17 features used in f18 +# C++14/17 features used in f18 + +```eval_rst +.. contents:: + :local: +``` The C++ dialect used in this project constitutes a subset of the standard C++ programming language and library features. @@ -32,7 +37,7 @@ (`std::tuple` is actually a C++11 feature, but I include it in this list because it's not particularly well known.) -### Sum types +## Sum types First, some background information to explain the need for sum types in f18. @@ -111,7 +116,7 @@ functions (or the forbidden `dynamic_cast`) to identify alternatives during analysis -### Product types +## Product types Many productions in the Fortran grammar describe a sequence of various sub-parses. @@ -133,7 +138,7 @@ It has also been handy for template metaprogramming that needs to work with lists of types. -### `std::optional` +## `std::optional` This simple little type is used wherever a value might or might not be present. diff --git a/flang/docs/C++style.md b/flang/docs/C++style.md --- a/flang/docs/C++style.md +++ b/flang/docs/C++style.md @@ -6,6 +6,15 @@ --> +# Flang C++ Style Guide + +```eval_rst +.. contents:: + :local: +``` + +This document captures the style guide rules that are followed in the Flang codebase. + ## In brief: * Use *clang-format* from llvm 7 diff --git a/flang/docs/Calls.md b/flang/docs/Calls.md --- a/flang/docs/Calls.md +++ b/flang/docs/Calls.md @@ -6,6 +6,13 @@ --> +# Representation of Fortran function calls + +```eval_rst +.. contents:: + :local: +``` + ## Procedure reference implementation protocol Fortran function and subroutine references are complicated. diff --git a/flang/docs/Character.md b/flang/docs/Character.md --- a/flang/docs/Character.md +++ b/flang/docs/Character.md @@ -6,9 +6,14 @@ --> -## Implementation of `CHARACTER` types in f18 +# Implementation of `CHARACTER` types in f18 -### Kinds and Character Sets +```eval_rst +.. contents:: + :local: +``` + +## Kinds and Character Sets The f18 compiler and runtime support three kinds of the intrinsic `CHARACTER` type of Fortran 2018. @@ -48,7 +53,7 @@ assumptions, especially for `KIND=1` users of ISO-8859 character sets besides Latin-1. -### Lengths +## Lengths Allocatable `CHARACTER` objects in Fortran may defer the specification of their lengths until the time of their allocation or whole (non-substring) @@ -76,7 +81,7 @@ "zero" dimension of a scalar `CHARACTER` value, but they cannot have strides. -### Concatenation +## Concatenation Fortran has one `CHARACTER`-valued intrinsic operator, `//`, which concatenates its operands (10.1.5.3). @@ -105,7 +110,7 @@ The f18 compiler has a general (but slow) means of implementing concatenation and a specialized (fast) option to optimize the most common case. -#### General concatenation +### General concatenation In the most general case, the f18 compiler's generated code and runtime support library represent the result as a deferred-length allocatable @@ -130,7 +135,7 @@ allocatable and the right-hand side is a temporary, use of the runtime's `MoveAlloc()` subroutine instead can save an allocation and a copy. -#### Optimized concatenation +### Optimized concatenation Scalar `CHARACTER(KIND=1)` expressions evaluated as the right-hand sides of assignments to independent substrings or whole variables that are not diff --git a/flang/docs/ControlFlowGraph.md b/flang/docs/ControlFlowGraph.md --- a/flang/docs/ControlFlowGraph.md +++ b/flang/docs/ControlFlowGraph.md @@ -6,6 +6,13 @@ --> +# Control Flow Graph + +```eval_rst +.. contents:: + :local: +``` + ## Concept After a Fortran subprogram has been parsed, its names resolved, and all its semantic constraints successfully checked, the parse tree of its diff --git a/flang/docs/Directives.md b/flang/docs/Directives.md --- a/flang/docs/Directives.md +++ b/flang/docs/Directives.md @@ -6,8 +6,9 @@ --> -Compiler directives supported by F18 -==================================== +# Compiler directives supported by Flang + +A list of non-standard directives supported by Flang * `!dir$ fixed` and `!dir$ free` select Fortran source forms. Their effect persists to the end of the current source file. diff --git a/flang/docs/Extensions.md b/flang/docs/Extensions.md --- a/flang/docs/Extensions.md +++ b/flang/docs/Extensions.md @@ -6,6 +6,13 @@ --> +# Fortran Extensions supported by Flang + +```eval_rst +.. contents:: + :local: +``` + As a general principle, this compiler will accept by default and without complaint many legacy features, extensions to the standard language, and features that have been deleted from the standard, @@ -16,8 +23,8 @@ standard specification of the Fortran programming language, are accepted if enabled by command-line options. -Intentional violations of the standard -====================================== +## Intentional violations of the standard + * Scalar `INTEGER` actual argument expressions (not variables!) are converted to the kinds of scalar `INTEGER` dummy arguments when the interface is explicit and the kinds differ. @@ -29,8 +36,8 @@ so long as they contain no executable code, no internal subprograms, and allocate no storage outside a named `COMMON` block. (C1415) -Extensions, deletions, and legacy features supported by default -=============================================================== +## Extensions, deletions, and legacy features supported by default + * Tabs in source * `<>` as synonym for `.NE.` and `/=` * `$` and `@` as legal characters in names @@ -123,8 +130,8 @@ * DATA statement initialization is allowed for procedure pointers outside structure constructors. -Extensions supported when enabled by options --------------------------------------------- +### Extensions supported when enabled by options + * C-style backslash escape sequences in quoted CHARACTER literals (but not Hollerith) [-fbackslash] * Logical abbreviations `.T.`, `.F.`, `.N.`, `.A.`, `.O.`, and `.X.` @@ -145,8 +152,8 @@ * Ignore occurrences of `IMPLICIT NONE` and `IMPLICIT NONE(TYPE)` [-fimplicit-none-type-never] -Extensions and legacy features deliberately not supported ---------------------------------------------------------- +### Extensions and legacy features deliberately not supported + * `.LG.` as synonym for `.NE.` * `REDIMENSION` * Allocatable `COMMON` @@ -189,8 +196,8 @@ PGI, Intel, and XLF support this in ways that are not numerically equivalent. PGI converts the arguments while Intel and XLF replace the specific by the related generic. -Preprocessing behavior -====================== +## Preprocessing behavior + * The preprocessor is always run, whatever the filename extension may be. * We respect Fortran comments in macro actual arguments (like GNU, Intel, NAG; unlike PGI and XLF) on the principle that macro calls should be treated diff --git a/flang/docs/FortranForCProgrammers.md b/flang/docs/FortranForCProgrammers.md --- a/flang/docs/FortranForCProgrammers.md +++ b/flang/docs/FortranForCProgrammers.md @@ -6,8 +6,12 @@ --> -Fortran For C Programmers -========================= +# Fortran For C Programmers + +```eval_rst +.. contents:: + :local: +``` This note is limited to essential information about Fortran so that a C or C++ programmer can get started more quickly with the language, @@ -16,8 +20,8 @@ Please see other sources to learn about Fortran's rich history, current applications, and modern best practices in new code. -Know This At Least ------------------- +## Know This At Least + * There have been many implementations of Fortran, often from competing vendors, and the standard language has been defined by U.S. and international standards organizations. The various editions of @@ -53,8 +57,8 @@ interfaces in compiled "modules", as well as legacy mechanisms for sharing data and interconnecting subprograms. -A Rosetta Stone ---------------- +## A Rosetta Stone + Fortran's language standard and other documentation uses some terminology in particular ways that might be unfamiliar. @@ -81,8 +85,8 @@ | Type-bound procedure | Kind of a C++ member function but not really | | Unformatted | Raw binary | -Data Types ----------- +## Data Types + There are five built-in ("intrinsic") types: `INTEGER`, `REAL`, `COMPLEX`, `LOGICAL`, and `CHARACTER`. They are parameterized with "kind" values, which should be treated as @@ -117,8 +121,8 @@ situations, like static data initialization or immediate conversion, where type is not necessary. -Arrays ------- +## Arrays + Arrays are not types in Fortran. Being an array is a property of an object or function, not of a type. Unlike C, one cannot have an array of arrays or an array of pointers, @@ -133,8 +137,8 @@ Expressions can manipulate arrays as multidimensional values, and the compiler will create the necessary loops. -Allocatables ------------- +## Allocatables + Modern Fortran programs use `ALLOCATABLE` data extensively. Such variables and derived type components are allocated dynamically. They are automatically deallocated when they go out of scope, much @@ -147,8 +151,8 @@ from the description of `ALLOCATABLE` to other topics; it's a feature that interacts with much of the rest of the language.) -I/O ---- +## I/O + Fortran's input/output features are built into the syntax of the language, rather than being defined by library interfaces as in C and C++. There are means for raw binary I/O and for "formatted" transfers to @@ -173,8 +177,8 @@ in which the compiler derives reasonable default formats based on data types. -Subprograms ------------ +## Subprograms + Fortran has both `FUNCTION` and `SUBROUTINE` subprograms. They share the same name space, but functions cannot be called as subroutines or vice versa. @@ -188,8 +192,8 @@ As is the case with C++ lambda expressions, internal procedures can reference names from their host subprograms. -Modules -------- +## Modules + Modern Fortran has good support for separate compilation and namespace management. The *module* is the basic unit of compilation, although independent @@ -204,8 +208,8 @@ aliases that have been added to the local scope, as Fortran has no means of qualifying references with module names. -Arguments ---------- +## Arguments + Functions and subroutines have "dummy" arguments that are dynamically associated with actual arguments during calls. Essentially, all argument passing in Fortran is by reference, not value. @@ -236,8 +240,8 @@ This is the opposite of the assumptions under which a C or C++ compiler must labor when trying to optimize code with pointers. -Overloading ------------ +## Overloading + Fortran supports a form of overloading via its interface feature. By default, an interface is a means for specifying prototypes for a set of subroutines and functions. @@ -250,8 +254,8 @@ This feature can be used to overload the built-in operators and some I/O statements, too. -Polymorphism ------------- +## Polymorphism + Fortran code can be written to accept data of some derived type or any extension thereof using `CLASS`, deferring the actual type to execution, rather than the usual `TYPE` syntax. @@ -261,8 +265,8 @@ possible specific types dynamically, when necessary. It's a little like C++17's `std::visit()` on a discriminated union. -Pointers --------- +## Pointers + Pointers are objects in Fortran, not data types. Pointers can point to data, arrays, and subprograms. A pointer can only point to data that has the `TARGET` attribute. @@ -287,8 +291,8 @@ A legacy feature, "Cray pointers", implements dynamic base addressing of one variable using an address stored in another. -Preprocessing -------------- +## Preprocessing + There is no standard preprocessing feature, but every real Fortran implementation has some support for passing Fortran source code through a variant of the standard C source preprocessor. @@ -302,8 +306,8 @@ (Since the F18 compiler always runs its built-in preprocessing stage, no special option or filename suffix is required.) -"Object Oriented" Programming ------------------------------ +## "Object Oriented" Programming + Fortran doesn't have member functions (or subroutines) in the sense that C++ does, in which a function has immediate access to the members of a specific instance of a derived type. @@ -325,8 +329,8 @@ support overloading) but this should be enough to get you started with the most common usage. -Pitfalls --------- +## Pitfalls + Variable initializers, e.g. `INTEGER :: J=123`, are _static_ initializers! They imply that the variable is stored in static storage, not on the stack, and the initialized value lasts only until the variable is assigned. diff --git a/flang/docs/FortranIR.md b/flang/docs/FortranIR.md --- a/flang/docs/FortranIR.md +++ b/flang/docs/FortranIR.md @@ -8,6 +8,11 @@ # Design: Fortran IR +```eval_rst +.. contents:: + :local: +``` + ## Introduction After semantic analysis is complete and it has been determined that the compiler has a legal Fortran program as input, the parse tree will be lowered to an intermediate representation for the purposes of high-level analysis and optimization. In this document, that intermediate representation will be called Fortran IR or FIR. The pass that converts from the parse tree and other data structures of the front-end to FIR will be called the "Burnside bridge". diff --git a/flang/docs/IORuntimeInternals.md b/flang/docs/IORuntimeInternals.md --- a/flang/docs/IORuntimeInternals.md +++ b/flang/docs/IORuntimeInternals.md @@ -6,8 +6,12 @@ --> -Fortran I/O Runtime Library Internal Design -=========================================== +# Fortran I/O Runtime Library Internal Design + +```eval_rst +.. contents:: + :local: +``` This note is meant to be an overview of the design of the *implementation* of the f18 Fortran compiler's runtime support library for I/O statements. @@ -66,8 +70,7 @@ floating-point values in Fortran source programs and to emit them to module files. -Overview of Classes -=================== +## Overview of Classes A suite of C++ classes and class templates are composed to construct the Fortran I/O runtime support library. @@ -79,16 +82,16 @@ modified; use `grep` or an IDE to discover these classes in the source for now. (Sorry!) -`Terminator` ----------- +### `Terminator` + A general facility for the entire library, `Terminator` latches a source program statement location in terms of an unowned pointer to its source file path name and line number and uses them to construct a fatal error message if needed. It is used for both user program errors and internal runtime library crashes. -`IoErrorHandler` --------------- +### `IoErrorHandler` + When I/O error conditions arise at runtime that the Fortran program might have the privilege to handle itself via `ERR=`, `END=`, or `EOR=` labels and/or by an `IOSTAT=` variable, this subclass of @@ -96,8 +99,8 @@ It sorts out priorities in the case of multiple errors and determines the final `IOSTAT=` value at the end of an I/O statement. -`MutableModes` ------------- +### `MutableModes` + Fortran's formatted I/O statements are affected by a suite of modes that can be configured by `OPEN` statements, overridden by data transfer I/O statement control lists, and further overridden @@ -108,8 +111,8 @@ The modes in force at the time each data item is processed constitute a member of each `DataEdit`. -`DataEdit` --------- +### `DataEdit` + Represents a single data edit descriptor from a `FORMAT` statement or `FMT=` character value, with some hidden extensions to also support formatting of list-directed transfers. @@ -119,8 +122,8 @@ encoded in the `DataEdit` as a simple capitalized character (or two) and some optional field widths. -`FormatControl<>` ---------------- +### `FormatControl<>` + This class template traverses a `FORMAT` statement's contents (or `FMT=` character value) to extract data edit descriptors like `E20.14` to serve each item in an I/O data transfer statement's *io-list*, @@ -142,32 +145,32 @@ The `DefaultFormatControlCallbacks` structure summarizes the API expected by `FormatControl` from its class template actual arguments. -`OpenFile` --------- +### `OpenFile` + This class encapsulates all (I hope) the operating system interfaces used to interact with the host's filesystems for operations on external units. Asynchronous I/O interfaces are faked for now with synchronous operations and deferred results. -`ConnectionState` ---------------- +### `ConnectionState` + An active connection to an external or internal unit maintains the common parts of its state in this subclass of `ConnectionAttributes`. The base class holds state that should not change during the lifetime of the connection, while the subclass maintains state that may change during I/O statement execution. -`InternalDescriptorUnit` ----------------------- +### `InternalDescriptorUnit` + When I/O is being performed from/to a Fortran `CHARACTER` array rather than an external file, this class manages the standard interoperable descriptor used to access its elements as records. It has the necessary interfaces to serve as an actual argument to the `FormatControl` class template. -`FileFrame<>` ------------ +### `FileFrame<>` + This CRTP class template isolates all of the complexity involved between an external unit's `OpenFile` and the buffering requirements imposed by the capabilities of Fortran `FORMAT` control edit @@ -192,8 +195,8 @@ As a CRTP class template, `FileFrame` accesses the raw filesystem facilities it needs from `*this`. -`ExternalFileUnit` ----------------- +### `ExternalFileUnit` + This class mixes in `ConnectionState`, `OpenFile`, and `FileFrame` to represent the state of an open (or soon to be opened) external file descriptor as a Fortran @@ -210,8 +213,8 @@ probe the map to convert Fortran `UNIT=` numbers from I/O statements into references to active units. -`IoStatementBase` ---------------- +### `IoStatementBase` + The subclasses of `IoStatementBase` each encapsulate and maintain the state of one active Fortran I/O statement across the several I/O runtime library API function calls it may comprise. @@ -239,8 +242,8 @@ program may supply stack space to the I/O runtime support library for this purpose. -`IoStatementState` ----------------- +### `IoStatementState` + F18's Fortran I/O runtime support library defines and implements an API that uses a sequence of function calls to implement each Fortran I/O statement. @@ -269,8 +272,8 @@ as a weird variation of internal I/O since there's no `ExternalFileUnit` available to hold its `IoStatementBase` subclass or `IoStatementState`. -A Narrative Overview Of `PRINT *, 'HELLO, WORLD'` -================================================= +## A Narrative Overview Of `PRINT *, 'HELLO, WORLD'` + 1. When the compiled Fortran program begins execution at the `main()` entry point exported from its main program, it calls `ProgramStart()` with its arguments and environment. diff --git a/flang/docs/ImplementingASemanticCheck.md b/flang/docs/ImplementingASemanticCheck.md --- a/flang/docs/ImplementingASemanticCheck.md +++ b/flang/docs/ImplementingASemanticCheck.md @@ -5,14 +5,20 @@ SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception --> -# Introduction +# How to implement a Sematic Check in Flang + +```eval_rst +.. contents:: + :local: +``` + I recently added a semantic check to the f18 compiler front end. This document describes my thought process and the resulting implementation. For more information about the compiler, start with the [compiler overview](Overview.md). -# Problem definition +## Problem definition In the 2018 Fortran standard, section 11.1.7.4.3, paragraph 2, states that: @@ -29,7 +35,7 @@ INTENT(INOUT). Previously, I had implemented similar checks for SUBROUTINE calls. -# Creating a test +## Creating a test My first step was to create a test case to cause the problem. I called it testfun.f90 and used it to check the behavior of other Fortran compilers. Here's the initial version: @@ -94,14 +100,14 @@ ```fortran dummyArg = 216 ``` -# Analysis and implementation planning +## Analysis and implementation planning I then considered what I needed to do. I needed to detect situations where an active DO variable was passed to a dummy argument with `INTENT(OUT)` or `INTENT(INOUT)`. Once I detected such a situation, I needed to produce a message that highlighted the erroneous source code. -## Deciding where to add the code to the compiler +### Deciding where to add the code to the compiler This new semantic check would depend on several types of information -- the parse tree, source code location information, symbols, and expressions. Thus I needed to put my new code in a place in the compiler after the parse tree had @@ -151,7 +157,7 @@ the file `lib/Semantics/check-do.cpp` where most of the semantic checking for DO statements already lived. -## Taking advantage of prior work +### Taking advantage of prior work When implementing a similar check for SUBROUTINE calls, I created a utility functions in `lib/Semantics/semantics.cpp` to emit messages if a symbol corresponding to an active DO variable was being potentially modified: @@ -173,7 +179,7 @@ The first and third are needed since they're required to call the utility functions. The second is needed to determine whether to call them. -## Finding the source location +### Finding the source location The source code location information that I'd need for the error message must come from the parse tree. I looked in the file `include/flang/Parser/parse-tree.h` and determined that a `struct Expr` @@ -181,7 +187,7 @@ source`. Thus, if I visited a `parser::Expr` node, I could get the source location information for the associated expression. -## Determining the `INTENT` +### Determining the `INTENT` I knew that I could find the `INTENT` of the dummy argument associated with the actual argument from the function called `dummyIntent()` in the class `evaluate::ActualArgument` in the file `include/flang/Evaluate/call.h`. So @@ -248,7 +254,7 @@ me the `INTENT` of all of the dummy arguments in a FUNCTION call. Thus, I would have the second piece of information I needed. -## Determining if the actual argument is a variable +### Determining if the actual argument is a variable I also guessed that I could determine if the `evaluate::ActualArgument` consisted of a variable. @@ -264,9 +270,9 @@ argument, and a symbol that I could use to determine whether the actual argument was an active DO variable. -# Implementation +## Implementation -## Adding a parse tree visitor +### Adding a parse tree visitor I started my implementation by adding a visitor for `parser::Expr` nodes. Since this analysis is part of DO construct checking, I did this in `lib/Semantics/check-do.cpp`. I added a print statement to the visitor to @@ -308,7 +314,7 @@ now had one of the three pieces of information needed to detect and report errors. -## Collecting the actual arguments +### Collecting the actual arguments To get the `INTENT` of the dummy arguments and the `semantics::Symbol` associated with the actual argument, I needed to find all of the actual arguments embedded in an expression that contained a FUNCTION call. So my next step was to write the @@ -474,7 +480,7 @@ So far, so good. -## Finding the `INTENT` of the dummy argument +### Finding the `INTENT` of the dummy argument I now wanted to find the `INTENT` of the dummy argument associated with the arguments in the set. As mentioned earlier, the type `evaluate::ActualArgument` has a member function called `dummyIntent()` @@ -518,7 +524,7 @@ So far, so good. -## Finding the symbols for arguments that are variables +### Finding the symbols for arguments that are variables The third and last piece of information I needed was to determine if a variable was being passed as an actual argument. In such cases, I wanted to get the symbol table node (`semantics::Symbol`) for the variable. My starting point was the @@ -638,7 +644,7 @@ Sweet. -## Emitting the messages +### Emitting the messages At this point, using the source location information from the original `parser::Expr`, I had enough information to plug into the exiting interfaces for emitting messages for active DO variables. I modified the @@ -701,7 +707,7 @@ Even sweeter. -# Improving the test case +## Improving the test case At this point, my implementation seemed to be working. But I was concerned about the limitations of my test case. So I augmented it to include arguments other than `INTENT(OUT)` and more complex expressions. Luckily, my @@ -762,7 +768,7 @@ end subroutine s ``` -# Submitting the pull request +## Submitting the pull request At this point, my implementation seemed functionally complete, so I stripped out all of the debug statements, ran `clang-format` on it and reviewed it to make sure that the names were clear. Here's what I ended up with: @@ -790,7 +796,7 @@ I then created a pull request to get review comments. -# Responding to pull request comments +## Responding to pull request comments I got feedback suggesting that I use an `if` statement rather than a `case` statement. Another comment reminded me that I should look at the code I'd previously writted to do a similar check for SUBROUTINE calls to see diff --git a/flang/docs/Intrinsics.md b/flang/docs/Intrinsics.md --- a/flang/docs/Intrinsics.md +++ b/flang/docs/Intrinsics.md @@ -8,6 +8,11 @@ # A categorization of standard (2018) and extended Fortran intrinsic procedures +```eval_rst +.. contents:: + :local: +``` + This note attempts to group the intrinsic procedures of Fortran into categories of functions or subroutines with similar interfaces as an aid to comprehension beyond that which might be gained from the standard's @@ -53,14 +58,14 @@ may appear within the brackets to preserve the order of arguments (e.g., `COUNT`). -# Elemental intrinsic functions +## Elemental intrinsic functions Pure elemental semantics apply to these functions, to wit: when one or more of the actual arguments are arrays, the arguments must be conformable, and the result is also an array. Scalar arguments are expanded when the arguments are not all scalars. -## Elemental intrinsic functions that may have unrestricted specific procedures +### Elemental intrinsic functions that may have unrestricted specific procedures When an elemental intrinsic function is documented here as having an _unrestricted specific name_, that name may be passed as an actual @@ -349,7 +354,7 @@ `VERIFY` is essentially the opposite: it returns the index of the first (or last) character in `STRING` that is *not* present in `SET`, or zero if all are. -# Transformational intrinsic functions +## Transformational intrinsic functions This category comprises a large collection of intrinsic functions that are collected together because they somehow transform their arguments @@ -372,7 +377,7 @@ 1. The type `any` here denotes any intrinsic or derived type. 1. The notation `(..)` denotes an array of any rank (but not an assumed-rank array). -## Logical reduction transformational intrinsic functions +### Logical reduction transformational intrinsic functions ``` ALL(LOGICAL(k) MASK(..) [, DIM ]) -> LOGICAL(k) ANY(LOGICAL(k) MASK(..) [, DIM ]) -> LOGICAL(k) @@ -380,7 +385,7 @@ PARITY(LOGICAL(k) MASK(..) [, DIM ]) -> LOGICAL(k) ``` -## Numeric reduction transformational intrinsic functions +### Numeric reduction transformational intrinsic functions ``` IALL(INTEGER(k) ARRAY(..) [, DIM, MASK ]) -> INTEGER(k) IANY(INTEGER(k) ARRAY(..) [, DIM, MASK ]) -> INTEGER(k) @@ -392,7 +397,7 @@ `NORM2` generalizes `HYPOT` by computing `SQRT(SUM(X*X))` while avoiding spurious overflows. -## Extrema reduction transformational intrinsic functions +### Extrema reduction transformational intrinsic functions ``` MAXVAL(relational(k) ARRAY(..) [, DIM, MASK ]) -> relational(k) MINVAL(relational(k) ARRAY(..) [, DIM, MASK ]) -> relational(k) @@ -419,7 +424,7 @@ MINLOC(relational ARRAY(..) [, DIM, MASK, KIND=KIND(0), BACK=.FALSE. ]) ``` -## Data rearrangement transformational intrinsic functions +### Data rearrangement transformational intrinsic functions The optional `DIM` argument to these functions must be a scalar integer of any kind, and it takes a default value of 1 when absent. @@ -475,7 +480,7 @@ ``` `FIELD` has same type and kind as `VECTOR` and is conformable with `MASK`. -## Other transformational intrinsic functions +### Other transformational intrinsic functions ``` BESSEL_JN(INTEGER(n1) N1, INTEGER(n2) N2, REAL(k) X) -> REAL(k) vector (MAX(N2-N1+1,0)) BESSEL_YN(INTEGER(n1) N1, INTEGER(n2) N2, REAL(k) X) -> REAL(k) vector (MAX(N2-N1+1,0)) @@ -517,7 +522,7 @@ An assumed-rank array may be passed to `SHAPE`, and if it is associated with an assumed-size array, the last element of the result will be -1. -## Coarray transformational intrinsic functions +### Coarray transformational intrinsic functions ``` FAILED_IMAGES([scalar TEAM_TYPE TEAM, KIND=KIND(0)]) -> INTEGER(KIND) vector GET_TEAM([scalar INTEGER(?) LEVEL]) -> scalar TEAM_TYPE @@ -532,10 +537,10 @@ The result of `THIS_IMAGE` is a scalar if `DIM` is present or if `COARRAY` is absent, and a vector whose length is the corank of `COARRAY` otherwise. -# Inquiry intrinsic functions +## Inquiry intrinsic functions These are neither elemental nor transformational; all are pure. -## Type inquiry intrinsic functions +### Type inquiry intrinsic functions All of these functions return constants. The value of the argument is not used, and may well be undefined. ``` @@ -554,7 +559,7 @@ TINY(REAL(k) X(..)) -> scalar REAL(k) ``` -## Bound and size inquiry intrinsic functions +### Bound and size inquiry intrinsic functions The results are scalar when `DIM` is present, and a vector of length=(co)rank(`(CO)ARRAY`) when `DIM` is absent. ``` @@ -567,7 +572,7 @@ Assumed-rank arrays may be used with `LBOUND`, `SIZE`, and `UBOUND`. -## Object characteristic inquiry intrinsic functions +### Object characteristic inquiry intrinsic functions ``` ALLOCATED(any type ALLOCATABLE ARRAY) -> scalar default LOGICAL ALLOCATED(any type ALLOCATABLE SCALAR) -> scalar default LOGICAL @@ -584,11 +589,11 @@ An assumed-rank array may be used with `IS_CONTIGUOUS` and `RANK`. -# Intrinsic subroutines +## Intrinsic subroutines (*TODO*: complete these descriptions) -## One elemental intrinsic subroutine +### One elemental intrinsic subroutine ``` INTERFACE SUBROUTINE MVBITS(FROM, FROMPOS, LEN, TO, TOPOS) @@ -602,7 +607,7 @@ END INTERFACE ``` -## Non-elemental intrinsic subroutines +### Non-elemental intrinsic subroutines ``` CALL CPU_TIME(REAL INTENT(OUT) TIME) ``` @@ -627,7 +632,7 @@ CALL SYSTEM_CLOCK([COUNT, COUNT_RATE, COUNT_MAX]) ``` -## Atomic intrinsic subroutines +### Atomic intrinsic subroutines ``` CALL ATOMIC_ADD(ATOM, VALUE [, STAT=]) CALL ATOMIC_AND(ATOM, VALUE [, STAT=]) @@ -642,7 +647,7 @@ CALL ATOMIC_XOR(ATOM, VALUE [, STAT=]) ``` -## Collective intrinsic subroutines +### Collective intrinsic subroutines ``` CALL CO_BROADCAST CALL CO_MAX @@ -651,8 +656,8 @@ CALL CO_SUM ``` -# Non-standard intrinsics -## PGI +## Non-standard intrinsics +### PGI ``` AND, OR, XOR LSHIFT, RSHIFT, SHIFT @@ -666,7 +671,7 @@ LOC ``` -## Intel +### Intel ``` DCMPLX(X,Y), QCMPLX(X,Y) DREAL(DOUBLE COMPLEX A) -> DOUBLE PRECISION @@ -689,12 +694,12 @@ MALLOC ``` -# Intrinsic Procedure Support in f18 +## Intrinsic Procedure Support in f18 This section gives an overview of the support inside f18 libraries for the intrinsic procedures listed above. It may be outdated, refer to f18 code base for the actual support status. -## Semantic Analysis +### Semantic Analysis F18 semantic expression analysis phase detects intrinsic procedure references, validates the argument types and deduces the return types. This phase currently supports all the intrinsic procedures listed above but the ones in the table below. @@ -710,7 +715,7 @@ | Collective intrinsic subroutines | CO_BROADCAST &al. | -## Intrinsic Function Folding +### Intrinsic Function Folding Fortran Constant Expressions can contain references to a certain number of intrinsic functions (see Fortran 2018 standard section 10.1.12 for more details). Constant Expressions may be used to define kind arguments. Therefore, the semantic @@ -724,7 +729,7 @@ it is using host hardware types or not). The status of intrinsic function folding support is given in the sub-sections below. -### Intrinsic Functions with Host Independent Folding Support +#### Intrinsic Functions with Host Independent Folding Support Implementations using f18 scalar types enables folding intrinsic functions on any host and with any possible type kind supported by f18. The intrinsic functions listed below are folded using host independent implementations. @@ -736,7 +741,7 @@ | COMPLEX | CMPLX, CONJG | | LOGICAL | BGE, BGT, BLE, BLT | -### Intrinsic Functions with Host Dependent Folding Support +#### Intrinsic Functions with Host Dependent Folding Support Implementations using the host runtime may not be available for all supported f18 types depending on the host hardware types and the libraries available on the host. The actual support on a host depends on what the host hardware types are. diff --git a/flang/docs/LabelResolution.md b/flang/docs/LabelResolution.md --- a/flang/docs/LabelResolution.md +++ b/flang/docs/LabelResolution.md @@ -8,6 +8,11 @@ # Semantics: Resolving Labels and Construct Names +```eval_rst +.. contents:: + :local: +``` + ## Overview After the Fortran input file(s) has been parsed into a syntax tree, the compiler must check that the program checks semantically. Target labels must be checked and violations of legal semantics should be reported to the user. diff --git a/flang/docs/ModFiles.md b/flang/docs/ModFiles.md --- a/flang/docs/ModFiles.md +++ b/flang/docs/ModFiles.md @@ -8,6 +8,11 @@ # Module Files +```eval_rst +.. contents:: + :local: +``` + Module files hold information from a module that is necessary to compile program units that depend on the module. diff --git a/flang/docs/OpenMP-4.5-grammar.txt b/flang/docs/OpenMP-4.5-grammar.md rename from flang/docs/OpenMP-4.5-grammar.txt rename to flang/docs/OpenMP-4.5-grammar.md --- a/flang/docs/OpenMP-4.5-grammar.txt +++ b/flang/docs/OpenMP-4.5-grammar.md @@ -1,18 +1,16 @@ -#===-- docs/OpenMP-4.5-grammar.txt --------------------------------===# -# -# 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 -# -#===------------------------------------------------------------------------===# +# OpenMP 4.5 Grammar -# OpenMP 4.5 Specifications +Grammar used by Flang to parse OpenMP 4.5. +## OpenMP 4.5 Specifications +``` 2 omp-directive -> sentinel directive-name [clause[ [,] clause]...] 2.1.1 sentinel -> !$omp | c$omp | *$omp 2.1.2 sentinel -> !$omp +``` -# directive-name +## directive-name +``` 2.5 parallel -> PARALLEL [parallel-clause[ [,] parallel-clause]...] parallel-clause -> if-clause | num-threads-clause | @@ -464,3 +462,4 @@ ALLOC | RELEASE | DELETE 2.15.5.2 defaultmap -> DEFAULTMAP (TOFROM:SCALAR) +``` diff --git a/flang/docs/OpenMP-semantics.md b/flang/docs/OpenMP-semantics.md --- a/flang/docs/OpenMP-semantics.md +++ b/flang/docs/OpenMP-semantics.md @@ -8,6 +8,11 @@ # OpenMP Semantic Analysis +```eval_rst +.. contents:: + :local: +``` + ## OpenMP for F18 1. Define and document the parse tree representation for diff --git a/flang/docs/OptionComparison.md b/flang/docs/OptionComparison.md --- a/flang/docs/OptionComparison.md +++ b/flang/docs/OptionComparison.md @@ -6,14 +6,21 @@ --> -# Compiler options +# Compiler options comparison + +```eval_rst +.. contents:: + :local: +``` This document catalogs the options processed by F18's peers/competitors. Much of the document is taken up by a set of tables that list the options categorized into different topics. Some of the table headings link to more information about the contents of the tables. For example, the table on **Standards conformance** options links to [notes on Standards conformance](#standards). -**There's also important information in the ___[Notes section](#notes)___ near the end of the document on how this data was gathered and what ___is___ and ___is not___ included in this document.** +**There's also important information in the ___[Appendix section](#appendix)___ near the end of the document on how this data was gathered and what ___is___ and ___is not___ included in this document.** Note that compilers may support language features without having an option for them. Such cases are frequently, but not always noted in this document. +## Categorisation of Options +
Standards conformance @@ -1183,7 +1190,7 @@ -## Notes +## Notes **Standards conformance:** @@ -1290,7 +1297,7 @@ **Warn for bad call checking**: This Cray option ("-eb") issues a warning message rather than an error message when the compiler detects a call to a procedure with one or more dummy arguments having the TARGET, VOLATILE or ASYNCHRONOUS attribute and there is not an explicit interface definition. -## Notes +## Appendix ### What is and is not included diff --git a/flang/docs/Overview.md b/flang/docs/Overview.md --- a/flang/docs/Overview.md +++ b/flang/docs/Overview.md @@ -8,6 +8,11 @@ # Overview of Compiler Phases +```eval_rst +.. contents:: + :local: +``` + Each phase produces either correct output or fatal errors. ## Prescan and Preprocess diff --git a/flang/docs/ParserCombinators.md b/flang/docs/ParserCombinators.md --- a/flang/docs/ParserCombinators.md +++ b/flang/docs/ParserCombinators.md @@ -6,6 +6,15 @@ --> +# Parser Combinators + +```eval_rst +.. contents:: + :local: +``` + +This document is a primer on Parser Combinators and their use in Flang. + ## Concept The Fortran language recognizer here can be classified as an LL recursive descent parser. It is composed from a *parser combinator* library that diff --git a/flang/docs/Parsing.md b/flang/docs/Parsing.md --- a/flang/docs/Parsing.md +++ b/flang/docs/Parsing.md @@ -6,8 +6,13 @@ --> -The F18 Parser -============== +# The F18 Parser + +```eval_rst +.. contents:: + :local: +``` + This program source code implements a parser for the Fortran programming language. @@ -42,8 +47,8 @@ of the Parsing class correspond to the two major passes of the parser, which are described below. -Prescanning and Preprocessing ------------------------------ +## Prescanning and Preprocessing + The first pass is performed by an instance of the Prescanner class, with help from an instance of Preprocessor. @@ -100,8 +105,8 @@ for debugging, being as it is a simple value forwarded from the first major pass of the compiler to the second. -Source Provenance ------------------ +## Source Provenance + The prescanner constructs a chronicle of every file that is read by the parser, viz. the original source file and all others that it directly or indirectly includes. One copy of the content of each of these files @@ -124,8 +129,8 @@ stream, or to contiguous ranges thereof, are used as source position indicators within the parser and in the parse tree. -Messages --------- +## Messages + Message texts, and snprintf-like formatting strings for constructing messages, are instantiated in the various components of the parser with C++ user defined character literals tagged with `_err_en_US` and `_en_US` @@ -134,8 +139,8 @@ for localization. As described above, messages are associated with source code positions by means of provenance values. -The Parse Tree --------------- +## The Parse Tree + Each of the ca. 450 numbered requirement productions in the standard Fortran language grammar, as well as the productions implied by legacy extensions and preserved obsolescent features, maps to a distinct class @@ -174,8 +179,8 @@ There is a general purpose library by means of which parse trees may be traversed. -Parsing -------- +## Parsing + This compiler attempts to recognize the entire cooked character stream (see above) as a Fortran program. It records the reductions made during a successful recognition as a parse tree value. The recognized grammar @@ -203,8 +208,8 @@ complicated recognizers and their correspondences to the construction of parse tree values. -Unparsing ---------- +## Unparsing + Parse trees can be converted back into free form Fortran source code. This formatter is not really a classical "pretty printer", but is more of a data structure dump whose output is suitable for compilation diff --git a/flang/docs/Preprocessing.md b/flang/docs/Preprocessing.md --- a/flang/docs/Preprocessing.md +++ b/flang/docs/Preprocessing.md @@ -6,11 +6,15 @@ --> -Fortran Preprocessing -===================== +# Fortran Preprocessing + +```eval_rst +.. contents:: + :local: +``` + +## Behavior common to (nearly) all compilers: -Behavior common to (nearly) all compilers: ------------------------------------------- * Macro and argument names are sensitive to case. * Fixed form right margin clipping after column 72 (or 132) has precedence over macro name recognition, and also over @@ -39,9 +43,8 @@ * A `#define` directive intermixed with continuation lines can't define a macro that's invoked earlier in the same continued statement. -Behavior that is not consistent over all extant compilers but which -probably should be uncontroversial: ------------------------------------ +## Behavior that is not consistent over all extant compilers but which probably should be uncontroversial: + * Invoked macro names can straddle a Fortran line continuation. * ... unless implicit fixed form card padding intervenes; i.e., in fixed form, a continued macro name has to be split at column @@ -65,8 +68,8 @@ directive indicator. * `#define KWM !` allows KWM to signal a comment. -Judgement calls, where precedents are unclear: ----------------------------------------------- +## Judgement calls, where precedents are unclear: + * Expressions in `#if` and `#elif` should support both Fortran and C operators; e.g., `#if 2 .LT. 3` should work. * If a function-like macro does not close its parentheses, line @@ -84,16 +87,16 @@ lines, it may or may not affect text in the continued statement that appeared before the directive. -Behavior that few compilers properly support (or none), but should: -------------------------------------------------------------------- +## Behavior that few compilers properly support (or none), but should: + * A macro invocation can straddle free form continuation lines in all of their forms, with continuation allowed in the name, before the arguments, and within the arguments. * Directives can be capitalized in free form, too. * `__VA_ARGS__` and `__VA_OPT__` work in variadic function-like macros. -In short, a Fortran preprocessor should work as if: ---------------------------------------------------- +## In short, a Fortran preprocessor should work as if: + 1. Fixed form lines are padded up to column 72 (or 132) and clipped thereafter. 2. Fortran comments are removed. 3. C-style line continuations are processed in preprocessing directives. @@ -125,8 +128,7 @@ OpenMP-style directives that look like comments are not addressed by this scheme but are obvious extensions. -Appendix -======== +## Appendix `N` in the table below means "not supported"; this doesn't mean a bug, it just means that a particular behavior was not observed. diff --git a/flang/docs/PullRequestChecklist.md b/flang/docs/PullRequestChecklist.md --- a/flang/docs/PullRequestChecklist.md +++ b/flang/docs/PullRequestChecklist.md @@ -36,7 +36,7 @@ clang-format will do this for most code. But you may need to break up long strings. * Review declarations for proper use of `constexpr` and `const`. -* Follow the C++ [naming guidelines](C++style.md#naming). +* Follow the C++ [naming guidelines](C++style.html#naming) * Ensure that the names evoke their purpose and are consistent with existing code. * Used braced initializers. * Review pointer and reference types to make sure that you're using them diff --git a/flang/docs/RuntimeDescriptor.md b/flang/docs/RuntimeDescriptor.md --- a/flang/docs/RuntimeDescriptor.md +++ b/flang/docs/RuntimeDescriptor.md @@ -6,6 +6,13 @@ --> +# Runtime Descriptors + +```eval_rst +.. contents:: + :local: +``` + ## Concept The properties that characterize data values and objects in Fortran programs must sometimes be materialized when the program runs. diff --git a/flang/docs/Semantics.md b/flang/docs/Semantics.md --- a/flang/docs/Semantics.md +++ b/flang/docs/Semantics.md @@ -8,6 +8,11 @@ # Semantic Analysis +```eval_rst +.. contents:: + :local: +``` + The semantic analysis pass determines if a syntactically correct Fortran program is is legal by enforcing the constraints of the language. diff --git a/flang/docs/conf.py b/flang/docs/conf.py --- a/flang/docs/conf.py +++ b/flang/docs/conf.py @@ -46,12 +46,23 @@ else: source_parsers = {'.md': 'recommonmark.parser.CommonMarkParser'} source_suffix['.md'] = 'markdown' + extensions.append('sphinx_markdown_tables') + + # Setup AutoStructify for inline .rst toctrees in index.md + from recommonmark.transform import AutoStructify + def setup(app): + # Disable inline math to avoid + # https://github.com/readthedocs/recommonmark/issues/120 in Extensions.md + app.add_config_value('recommonmark_config', { + 'enable_inline_math': False + }, True) + app.add_transform(AutoStructify) # The encoding of source files. #source_encoding = 'utf-8-sig' # The master toctree document. -master_doc = 'Overview' +master_doc = 'index' # General information about the project. project = u'Flang' diff --git a/flang/docs/f2018-grammar.txt b/flang/docs/f2018-grammar.md rename from flang/docs/f2018-grammar.txt rename to flang/docs/f2018-grammar.md --- a/flang/docs/f2018-grammar.txt +++ b/flang/docs/f2018-grammar.md @@ -1,11 +1,8 @@ -#===-- docs/f2018-grammar.txt -------------------------------------===# -# -# 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 -# -#===------------------------------------------------------------------------===# +# Fortran 2018 Grammar +Grammar used by Flang to parse Fortran 2018. + +``` R0001 digit -> 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 R0002 letter -> A | B | C | D | E | F | G | H | I | J | K | L | M | @@ -801,3 +798,4 @@ R1543 contains-stmt -> CONTAINS R1544 stmt-function-stmt -> function-name ( [dummy-arg-name-list] ) = scalar-expr +``` diff --git a/flang/docs/index.md b/flang/docs/index.md new file mode 100644 --- /dev/null +++ b/flang/docs/index.md @@ -0,0 +1,61 @@ +# Welcome to Flang's documentation + +Flang is LLVM's Fortran frontend + +```eval_rst +.. toctree:: + :titlesonly: + + ReleaseNotes +``` + +# Contributing to Flang + +```eval_rst +.. toctree:: + :titlesonly: + + FortranForCProgrammers + C++style + C++17 + PullRequestChecklist + ImplementingASemanticCheck +``` + +# Design Documents + +```eval_rst +.. toctree:: + :titlesonly: + + Overview + Preprocessing + Parsing + LabelResolution + ModFiles + Semantics + OpenMP-semantics + ControlFlowGraph + FortranIR + IORuntimeInternals + f2018-grammar.md + OpenMP-4.5-grammar.md + Directives + Extensions + Intrinsics + OptionComparison + ParserCombinators + RuntimeDescriptor + Calls + Character + ArrayComposition + BijectiveInternalNameUniquing +``` + +# Indices and tables + +```eval_rst +* :ref:`genindex` +* :ref:`modindex` +* :ref:`search` +```