1Fortran Preprocessing
2=====================
3
4Behavior common to (nearly) all compilers:
5------------------------------------------
6* Macro and argument names are sensitive to case.
7* Fixed form right margin clipping after column 72 (or 132)
8  has precedence over macro name recognition, and also over
9  recognition of function-like parentheses and arguments.
10* Fixed form right margin clipping does not apply to directive lines.
11* Macro names are not recognized as such when spaces are inserted
12  into their invocations in fixed form.
13  This includes spaces at the ends of lines that have been clipped
14  at column 72 (or whatever).
15* Text is rescanned after expansion of macros and arguments.
16* Macros are not expanded within quoted character literals or
17  quoted FORMAT edit descriptors.
18* Macro expansion occurs before any effective token pasting via fixed form
19  space removal.
20* C-like line continuations with backslash-newline are allowed in
21  directives, including the definitions of macro bodies.
22* `/* Old style C comments */` are ignored in directives and
23  removed from the bodies of macro definitions.
24* `// New style C comments` are not removed, since Fortran has OPERATOR(//).
25* C-like line continuations with backslash-newline can appear in
26  old-style C comments in directives.
27* After `#define FALSE TRUE`, `.FALSE.` is replaced by `.TRUE.`;
28  i.e., tokenization does not hide the names of operators or logical constants.
29* `#define KWM c` allows the use of `KWM` in column 1 as a fixed form comment
30  line indicator.
31* A `#define` directive intermixed with continuation lines can't
32  define a macro that's invoked earlier in the same continued statement.
33
34Behavior that is not consistent over all extant compilers but which
35probably should be uncontroversial:
36-----------------------------------
37* Invoked macro names can straddle a Fortran line continuation.
38* ... unless implicit fixed form card padding intervenes; i.e.,
39  in fixed form, a continued macro name has to be split at column
40  72 (or 132).
41* Comment lines may appear with continuations in a split macro names.
42* Function-like macro invocations can straddle a Fortran fixed form line
43  continuation between the name and the left parenthesis, and comment and
44  directive lines can be there too.
45* Function-like macro invocations can straddle a Fortran fixed form line
46  continuation between the parentheses, and comment lines can be there too.
47* Macros are not expanded within Hollerith constants or Hollerith
48  FORMAT edit descriptors.
49* Token pasting with `##` works in function-like macros.
50* Argument stringization with `#` works in function-like macros.
51* Directives can be capitalized (e.g., `#DEFINE`) in fixed form.
52* Fixed form clipping after column 72 or 132 is done before macro expansion,
53  not after.
54* C-like line continuation with backslash-newline can appear in the name of
55  a keyword-like macro definition.
56* If `#` is in column 6 in fixed form, it's a continuation marker, not a
57  directive indicator.
58* `#define KWM !` allows KWM to signal a comment.
59
60Judgement calls, where precedents are unclear:
61----------------------------------------------
62* Expressions in `#if` and `#elif` should support both Fortran and C
63  operators; e.g., `#if 2 .LT. 3` should work.
64* If a function-like macro does not close its parentheses, line
65  continuation should be assumed.
66* ... However, the leading parenthesis has to be on the same line as
67  the name of the function-like macro, or on a continuation line thereof.
68* If macros expand to text containing `&`, it doesn't work as a free form
69  line continuation marker.
70* `#define c 1` does not allow a `c` in column 1 to be used as a label
71  in fixed form, rather than as a comment line indicator.
72* IBM claims to be ISO C compliant and therefore recognizes trigraph sequences.
73* Fortran comments in macro actual arguments should be respected, on
74  the principle that a macro call should work like a function reference.
75* If a `#define` or `#undef` directive appears among continuation
76  lines, it may or may not affect text in the continued statement that
77  appeared before the directive.
78
79Behavior that few compilers properly support (or none), but should:
80-------------------------------------------------------------------
81* A macro invocation can straddle free form continuation lines in all of their
82  forms, with continuation allowed in the name, before the arguments, and
83  within the arguments.
84* Directives can be capitalized in free form, too.
85* `__VA_ARGS__` and `__VA_OPT__` work in variadic function-like macros.
86
87In short, a Fortran preprocessor should work as if:
88---------------------------------------------------
891. Fixed form lines are padded up to column 72 (or 132) and clipped thereafter.
902. Fortran comments are removed.
913. C-style line continuations are processed in preprocessing directives.
924. C old-style comments are removed from directives.
935. Fortran line continuations are processed (outside preprocessing directives).
94   Line continuation rules depend on source form.
95   Comment lines that are enabled compiler directives have their line
96   continuations processed.
97   Conditional compilation preprocessing directives (e.g., `#if`) may be
98   appear among continuation lines, and have their usual effects upon them.
996. Other preprocessing directives are processed and macros expanded.
100   Along the way, Fortran `INCLUDE` lines and preprocessor `#include` directives
101   are expanded, and all these steps applied recursively to the introduced text.
1027. Any Fortran comments created by macro replacement are removed.
103
104Steps 5 and 6 are interleaved with respect to the preprocessing state.
105Conditional compilation preprocessing directives always reflect only the macro
106definition state produced by the active `#define` and `#undef` preprocessing directives
107that precede them.
108
109If the source form is changed by means of a compiler directive (i.e.,
110`!DIR$ FIXED` or `FREE`) in an included source file, its effects cease
111at the end of that file.
112
113Last, if the preprocessor is not integrated into the Fortran compiler,
114new Fortran continuation line markers should be introduced into the final
115text.
116
117OpenMP-style directives that look like comments are not addressed by
118this scheme but are obvious extensions.
119
120Appendix
121========
122`N` in the table below means "not supported"; this doesn't
123mean a bug, it just means that a particular behavior was
124not observed.
125`E` signifies "error reported".
126
127The abbreviation `KWM` stands for "keyword macro" and `FLM` means
128"function-like macro".
129
130The first block of tests (`pp0*.F`) are all fixed-form source files;
131the second block (`pp1*.F90`) are free-form source files.
132
133```
134f18
135| pgfortran
136| | ifort
137| | | gfortran
138| | | | xlf
139| | | | | nagfor
140| | | | | |
141. . . . . .   pp001.F  keyword macros
142. . . . . .   pp002.F  #undef
143. . . . . .   pp003.F  function-like macros
144. . . . . .   pp004.F  KWMs case-sensitive
145. N . N N .   pp005.F  KWM split across continuation, implicit padding
146. N . N N .   pp006.F  ditto, but with intervening *comment line
147N N N N N N   pp007.F  KWM split across continuation, clipped after column 72
148. . . . . .   pp008.F  KWM with spaces in name at invocation NOT replaced
149. N . N N .   pp009.F  FLM call split across continuation, implicit padding
150. N . N N .   pp010.F  ditto, but with intervening *comment line
151N N N N N N   pp011.F  FLM call name split across continuation, clipped
152. N . N N .   pp012.F  FLM call name split across continuation
153. E . N N .   pp013.F  FLM call split between name and (
154. N . N N .   pp014.F  FLM call split between name and (, with intervening *comment
155. E . N N .   pp015.F  FLM call split between name and (, clipped
156. E . N N .   pp016.F  FLM call split between name and ( and in argument
157. . . . . .   pp017.F  KLM rescan
158. . . . . .   pp018.F  KLM rescan with #undef (so rescan is after expansion)
159. . . . . .   pp019.F  FLM rescan
160. . . . . .   pp020.F  FLM expansion of argument
161. . . . . .   pp021.F  KWM NOT expanded in 'literal'
162. . . . . .   pp022.F  KWM NOT expanded in "literal"
163. . E E . E   pp023.F  KWM NOT expanded in 9HHOLLERITH literal
164. . . E . .   pp024.F  KWM NOT expanded in Hollerith in FORMAT
165. . . . . .   pp025.F  KWM expansion is before token pasting due to fixed-form space removal
166. . . E . E   pp026.F  ## token pasting works in FLM
167E . . E E .   pp027.F  #DEFINE works in fixed form
168. N . N N .   pp028.F  fixed-form clipping done before KWM expansion on source line
169. . . . . .   pp029.F  \ newline allowed in #define
170. . . . . .   pp030.F  /* C comment */ erased from #define
171E E E E E E   pp031.F   // C++ comment NOT erased from #define
172. . . . . .   pp032.F  /* C comment */ \ newline erased from #define
173. . . . . .   pp033.F  /* C comment \ newline */ erased from #define
174. . . . . N   pp034.F  \ newline allowed in name on KWM definition
175. E . E E .   pp035.F  #if 2 .LT. 3 works
176. . . . . .   pp036.F  #define FALSE TRUE ...  .FALSE. -> .TRUE.
177N N N N N N   pp037.F  fixed-form clipping NOT applied to #define
178. . E . E E   pp038.F  FLM call with closing ')' on next line (not a continuation)
179E . E . E E   pp039.F  FLM call with '(' on next line (not a continuation)
180. . . . . .   pp040.F  #define KWM c, then KWM works as comment line initiator
181E . E . . E   pp041.F  use KWM expansion as continuation indicators
182N N N . . N   pp042.F  #define c 1, then use c as label in fixed-form
183. . . . N .   pp043.F  #define with # in column 6 is a continuation line in fixed-form
184E . . . . .   pp044.F  #define directive amid continuations
185. . . . . .   pp101.F90  keyword macros
186. . . . . .   pp102.F90  #undef
187. . . . . .   pp103.F90  function-like macros
188. . . . . .   pp104.F90  KWMs case-sensitive
189. N N N N N   pp105.F90  KWM call name split across continuation, with leading &
190. N N N N N   pp106.F90  ditto, with & ! comment
191N N E E N .   pp107.F90  KWM call name split across continuation, no leading &, with & ! comment
192N N E E N .   pp108.F90  ditto, but without & ! comment
193. N N N N N   pp109.F90  FLM call name split with leading &
194. N N N N N   pp110.F90  ditto, with & ! comment
195N N E E N .   pp111.F90  FLM call name split across continuation, no leading &, with & ! comment
196N N E E N .   pp112.F90  ditto, but without & ! comment
197. N N N N E   pp113.F90  FLM call split across continuation between name and (, leading &
198. N N N N E   pp114.F90  ditto, with & ! comment, leading &
199N N N N N .   pp115.F90  ditto, with & ! comment, no leading &
200N N N N N .   pp116.F90  FLM call split between name and (, no leading &
201. . . . . .   pp117.F90  KWM rescan
202. . . . . .   pp118.F90  KWM rescan with #undef, proving rescan after expansion
203. . . . . .   pp119.F90  FLM rescan
204. . . . . .   pp120.F90  FLM expansion of argument
205. . . . . .   pp121.F90  KWM NOT expanded in 'literal'
206. . . . . .   pp122.F90  KWM NOT expanded in "literal"
207. . E E . E   pp123.F90  KWM NOT expanded in Hollerith literal
208. . E E . E   pp124.F90  KWM NOT expanded in Hollerith in FORMAT
209E . . E E .   pp125.F90  #DEFINE works in free form
210. . . . . .   pp126.F90  \ newline works in #define
211N . E . E E   pp127.F90  FLM call with closing ')' on next line (not a continuation)
212E . E . E E   pp128.F90  FLM call with '(' on next line (not a continuation)
213. . N . . N   pp129.F90  #define KWM !, then KWM works as comment line initiator
214E . E . . E   pp130.F90  #define KWM &, use for continuation w/o pasting (ifort and nag seem to continue #define)
215```
216