forgot to add ffe.texi, the actual g77 front-end internals docs

From-SVN: r26518
This commit is contained in:
Craig Burley 1999-04-17 07:45:01 -04:00
parent 0f4668ef1a
commit 8a19a44a1f
1 changed files with 883 additions and 0 deletions

883
gcc/f/ffe.texi Normal file
View File

@ -0,0 +1,883 @@
@node Front End
@chapter Front End
@cindex GNU Fortran Front End (FFE)
@cindex FFE
@cindex @code{g77}, front end
@cindex front end, @code{g77}
This chapter describes some aspects of the design and implementation
of the @code{g77} front end.
@menu
* Philosophy of Code Generation::
* Two-pass Design::
* Challenges Posed::
* Transforming Statements::
* Transforming Expressions::
@end menu
@node Philosophy of Code Generation
@section Philosophy of Code Generation
Don't poke the bear.
The @code{g77} front end generates code
via the @code{gcc} back end.
@cindex GNU Back End (GBE)
@cindex GBE
@cindex @code{gcc}, back end
@cindex back end, gcc
@cindex code generator
The @code{gcc} back end (GBE) is a large, complex
labyrinth of intricate code
written in a combination of the C language
and specialized languages internal to @code{gcc}.
While the @emph{code} that implements the GBE
is written in a combination of languages,
the GBE itself is,
to the front end for a language like Fortran,
best viewed as a @emph{compiler}
that compiles its own, unique, language.
The GBE's ``source'', then, is written in this language,
which consists primarily of
a combination of calls to GBE functions
and @dfn{tree} nodes
(which are, themselves, created
by calling GBE functions).
So, the @code{g77} generates code by, in effect,
translating the Fortran code it reads
into a form ``written'' in the ``language''
of the @code{gcc} back end.
@cindex GBEL
@cindex GNU Back End Language (GBEL)
This language will heretofore be referred to as @dfn{GBEL},
for GNU Back End Language.
GBEL is an evolving language,
not fully specified in any published form
as of this writing.
It offers many facilities,
but its ``core'' facilities
are those that corresponding most directly
to those needed to support @code{gcc}
(compiling code written in GNU C).
The @code{g77} Fortran Front End (FFE)
is designed and implemented
to navigate the currents and eddies
of ongoing GBEL and @code{gcc} development
while also delivering on the potential
of an integrated FFE
(as compared to using a converter like @code{f2c}
and feeding the output into @code{gcc}).
Goals of the FFE's code-generation strategy include:
@itemize @bullet
@item
High likelihood of generation of correct code,
or, failing that, producing a fatal diagnostic or crashing.
@item
Generation of highly optimized code,
as directed by the user
via GBE-specific (versus @code{g77}-specific) constructs,
such as command-line options.
@item
Fast overall (FFE plus GBE) compilation.
@item
Preservation of source-level debugging information.
@end itemize
The strategies historically, and currently, used by the FFE
to achieve these goals include:
@itemize @bullet
@item
Use of GBEL constructs that most faithfully encapsulate
the semantics of Fortran.
@item
Avoidance of GBEL constructs that are so rarely used,
or limited to use in specialized situations not related to Fortran,
that their reliability and performance has not yet been established
as sufficient for use by the FFE.
@item
Flexible design, to readily accommodate changes to specific
code-generation strategies, perhaps governed by command-line options.
@end itemize
@cindex Bear-poking
@cindex Poking the bear
``Don't poke the bear'' somewhat summarizes the above strategies.
The GBE is the bear.
The FFE is designed and implemented to avoid poking it
in ways that are likely to just annoy it.
The FFE usually either tackles it head-on,
or avoids treating it in ways dissimilar to how
the @code{gcc} front end treats it.
For example, the FFE uses the native array facility in the back end
instead of the lower-level pointer-arithmetic facility
used by @code{gcc} when compiling @code{f2c} output).
Theoretically, this presents more opportunities for optimization,
faster compile times,
and the production of more faithful debugging information.
These benefits were not, however, immediately realized,
mainly because @code{gcc} itself makes little or no use
of the native array facility.
Complex arithmetic is a case study of the evolution of this strategy.
When originally implemented,
the GBEL had just evolved its own native complex-arithmetic facility,
so the FFE took advantage of that.
When porting @code{g77} to 64-bit systems,
it was discovered that the GBE didn't really
implement its native complex-arithmetic facility properly.
The short-term solution was to rewrite the FFE
to instead use the lower-level facilities
that'd be used by @code{gcc}-compiled code
(assuming that code, itself, didn't use the native complex type
provided, as an extension, by @code{gcc}),
since these were known to work,
and, in any case, if shown to not work,
would likely be rapidly fixed
(since they'd likely not work for vanilla C code in similar circumstances).
However, the rewrite accommodated the original, native approach as well
by offering a command-line option to select it over the emulated approach.
This allowed users, and especially GBE maintainers, to try out
fixes to complex-arithmetic support in the GBE
while @code{g77} continued to default to compiling more code correctly,
albeit producing (typically) slower executables.
As of April 1999, it appeared that the last few bugs
in the GBE's support of its native complex-arithmetic facility
were worked out.
The FFE was changed back to default to using that native facility,
leaving emulation as an option.
Other Fortran constructs---arrays, character strings,
complex division, @code{COMMON} and @code{EQUIVALENCE} aggregates,
and so on---involve issues similar to those pertaining to complex arithmetic.
So, it is possible that the history
of how the FFE handled complex arithmetic
will be repeated, probably in modified form
(and hopefully over shorter timeframes),
for some of these other facilities.
@node Two-pass Design
@section Two-pass Design
The FFE does not tell the GBE anything about a program unit
until after the last statement in that unit has been parsed.
(A program unit is a Fortran concept that corresponds, in the C world,
mostly closely to functions definitions in ISO C.
That is, a program unit in Fortran is like a top-level function in C.
Nested functions, found among the extensions offered by GNU C,
correspond roughly to Fortran's statement functions.)
So, while parsing the code in a program unit,
the FFE saves up all the information
on statements, expressions, names, and so on,
until it has seen the last statement.
At that point, the FFE revisits the saved information
(in what amounts to a second @dfn{pass} over the program unit)
to perform the actual translation of the program unit into GBEL,
ultimating in the generation of assembly code for it.
Some lookahead is performed during this second pass,
so the FFE could be viewed as a ``two-plus-pass'' design.
@menu
* Two-pass Code::
* Why Two Passes::
@end menu
@node Two-pass Code
@subsection Two-pass Code
Most of the code that turns the first pass (parsing)
into a second pass for code generation
is in @file{@value{path-g77}/std.c}.
It has external functions,
called mainly by siblings in @file{@value{path-g77}/stc.c},
that record the information on statements and expressions
in the order they are seen in the source code.
These functions save that information.
It also has an external function that revisits that information,
calling the siblings in @file{@value{path-g77}/ste.c},
which handles the actual code generation
(by generating GBEL code,
that is, by calling GBE routines
to represent and specify expressions, statements, and so on).
@node Why Two Passes
@subsection Why Two Passes
The need for two passes was not immediately evident
during the design and implementation of the code in the FFE
that was to produce GBEL.
Only after a few kludges,
to handle things like incorrectly-guessed @code{ASSIGN} label nature,
had been implemented,
did enough evidence pile up to make it clear
that @file{std.c} had to be introduced to intercept,
save, then revisit as part of a second pass,
the digested contents of a program unit.
Other such missteps have occurred during the evolution of the FFE,
because of the different goals of the FFE and the GBE.
Because the GBE's original, and still primary, goal
was to directly support the GNU C language,
the GBEL, and the GBE itself,
requires more complexity
on the part of most front ends
than it requires of @code{gcc}'s.
For example,
the GBEL offers an interface that permits the @code{gcc} front end
to implement most, or all, of the language features it supports,
without the front end having to
make use of non-user-defined variables.
(It's almost certainly the case that all of K&R C,
and probably ANSI C as well,
is handled by the @code{gcc} front end
without declaring such variables.)
The FFE, on the other hand, must resort to a variety of ``tricks''
to achieve its goals.
Consider the following C code:
@smallexample
int
foo (int a, int b)
@{
int c = 0;
if ((c = bar (c)) == 0)
goto done;
quux (c << 1);
done:
return c;
@}
@end smallexample
Note what kinds of objects are declared, or defined, before their use,
and before any actual code generation involving them
would normally take place:
@itemize @bullet
@item
Return type of function
@item
Entry point(s) of function
@item
Dummy arguments
@item
Variables
@item
Initial values for variables
@end itemize
Whereas, the following items can, and do,
suddenly appear ``out of the blue'' in C:
@itemize @bullet
@item
Label references
@item
Function references
@end itemize
Not surprisingly, the GBE faithfully permits the latter set of items
to be ``discovered'' partway through GBEL ``programs'',
just as they are permitted to in C.
Yet, the GBE has tended, at least in the past,
to be reticent to fully support similar ``late'' discovery
of items in the former set.
This makes Fortran a poor fit for the ``safe'' subset of GBEL.
Consider:
@smallexample
FUNCTION X (A, ARRAY, ID1)
CHARACTER*(*) A
DOUBLE PRECISION X, Y, Z, TMP, EE, PI
REAL ARRAY(ID1*ID2)
COMMON ID2
EXTERNAL FRED
ASSIGN 100 TO J
CALL FOO (I)
IF (I .EQ. 0) PRINT *, A(0)
GOTO 200
ENTRY Y (Z)
ASSIGN 101 TO J
200 PRINT *, A(1)
READ *, TMP
GOTO J
100 X = TMP * EE
RETURN
101 Y = TMP * PI
CALL FRED
DATA EE, PI /2.71D0, 3.14D0/
END
@end smallexample
Here are some observations about the above code,
which, while somewhat contrived,
conforms to the FORTRAN 77 and Fortran 90 standards:
@itemize @bullet
@item
The return type of function @samp{X} is not known
until the @samp{DOUBLE PRECISION} line has been parsed.
@item
Whether @samp{A} is a function or a variable
is not known until the @samp{PRINT *, A(0)} statement
has been parsed.
@item
The bounds of the array of argument @samp{ARRAY}
depend on a computation involving
the subsequent argument @samp{ID1}
and the blank-common member @samp{ID2}.
@item
Whether @samp{Y} and @samp{Z} are local variables,
additional function entry points,
or dummy arguments to additional entry points
is not known
until the @samp{ENTRY} statement is parsed.
@item
Similarly, whether @samp{TMP} is a local variable is not known
until the @samp{READ *, TMP} statement is parsed.
@item
The initial values for @samp{EE} and @samp{PI}
are not known until after the @samp{DATA} statement is parsed.
@item
Whether @samp{FRED} is a function returning type @code{REAL}
or a subroutine
(which can be thought of as returning type @code{void}
@emph{or}, to support alternate returns in a simple way,
type @code{int})
is not known
until the @samp{CALL FRED} statement is parsed.
@item
Whether @samp{100} is a @code{FORMAT} label
or the label of an executable statement
is not known
until the @samp{X =} statement is parsed.
(These two types of labels get @emph{very} different treatment,
especially when @code{ASSIGN}'ed.)
@item
That @samp{J} is a local variable is not known
until the first @samp{ASSIGN} statement is parsed.
(This happens @emph{after} executable code has been seen.)
@end itemize
Very few of these ``discoveries''
can be accommodated by the GBE as it has evolved over the years.
The GBEL doesn't support several of them,
and those it might appear to support
don't always work properly,
especially in combination with other GBEL and GBE features,
as implemented in the GBE.
(Had the GBE and its GBEL originally evolved to support @code{g77},
the shoe would be on the other foot, so to speak---most, if not all,
of the above would be directly supported by the GBEL,
and a few C constructs would probably not, as they are in reality,
be supported.
Both this mythical, and today's real, GBE caters to its GBEL
by, sometimes, scrambling around, cleaning up after itself---after
discovering that assumptions it made earlier during code generation
are incorrect.)
So, the FFE handles these discrepancies---between the order in which
it discovers facts about the code it is compiling,
and the order in which the GBEL and GBE support such discoveries---by
performing what amounts to two
passes over each program unit.
(A few ambiguities can remain at that point,
such as whether, given @samp{EXTERNAL BAZ}
and no other reference to @samp{BAZ} in the program unit,
it is a subroutine, a function, or a block-data---which, in C-speak,
governs its declared return type.
Fortunately, these distinctions are easily finessed
for the procedure, library, and object-file interfaces
supported by @code{g77}.)
@node Challenges Posed
@section Challenges Posed
Consider the following Fortran code, which uses various extensions
(including some to Fortran 90):
@smallexample
SUBROUTINE X(A)
CHARACTER*(*) A
COMPLEX CFUNC
INTEGER*2 CLOCKS(200)
INTEGER IFUNC
CALL SYSTEM_CLOCK (CLOCKS (IFUNC (CFUNC ('('//A//')'))))
@end smallexample
The above poses the following challenges to any Fortran compiler
that uses run-time interfaces, and a run-time library, roughly similar
to those used by @code{g77}:
@itemize @bullet
@item
Assuming the library routine that supports @code{SYSTEM_CLOCK}
expects to set an @code{INTEGER*4} variable via its @code{COUNT} argument,
the compiler must make available to it a temporary variable of that type.
@item
Further, after the @code{SYSTEM_CLOCK} library routine returns,
the compiler must ensure that the temporary variable it wrote
is copied into the appropriate element of the @samp{CLOCKS} array.
(This assumes the compiler doesn't just reject the code,
which it should if it is compiling under some kind of a "strict" option.)
@item
To determine the correct index into the @samp{CLOCKS} array,
(putting aside the fact that the index, in this particular case,
need not be computed until after
the @code{SYSTEM_CLOCK} library routine returns),
the compiler must ensure that the @code{IFUNC} function is called.
That requires evaluating its argument,
which requires, for @code{g77}
(assuming @code{-ff2c} is in force),
reserving a temporary variable of type @code{COMPLEX}
for use as a repository for the return value
being computed by @samp{CFUNC}.
@item
Before invoking @samp{CFUNC},
is argument must be evaluated,
which requires allocating, at run time,
a temporary large enough to hold the result of the concatenation,
as well as actually performing the concatenation.
@item
The large temporary needed during invocation of @code{CFUNC}
should, ideally, be deallocated
(or, at least, left to the GBE to dispose of, as it sees fit)
as soon as @code{CFUNC} returns,
which means before @code{IFUNC} is called
(as it might need a lot of dynamically allocated memory).
@end itemize
@code{g77} currently doesn't support all of the above,
but, so that it might someday, it has evolved to handle
at least some of the above requirements.
Meeting the above requirements is made more challenging
by conforming to the requirements of the GBEL/GBE combination.
@node Transforming Statements
@section Transforming Statements
Most Fortran statements are given their own block,
and, for temporary variables they might need, their own scope.
(A block is what distinguishes @samp{@{ foo (); @}}
from just @samp{foo ();} in C.
A scope is included with every such block,
providing a distinct name space for local variables.)
Label definitions for the statement precede this block,
so @samp{10 PRINT *, I} is handled more like
@samp{fl10: @{ @dots{} @}} than @samp{@{ fl10: @dots{} @}}
(where @samp{fl10} is just a notation meaning ``Fortran Label 10''
for the purposes of this document).
@menu
* Statements Needing Temporaries::
* Transforming DO WHILE::
* Transforming Iterative DO::
* Transforming Block IF::
* Transforming SELECT CASE::
@end menu
@node Statements Needing Temporaries
@subsection Statements Needing Temporaries
Any temporaries needed during, but not beyond,
execution of a Fortran statement,
are made local to the scope of that statement's block.
This allows the GBE to share storage for these temporaries
among the various statements without the FFE
having to manage that itself.
(The GBE could, of course, decide to optimize
management of these temporaries.
For example, it could, theoretically,
schedule some of the computations involving these temporaries
to occur in parallel.
More practically, it might leave the storage for some temporaries
``live'' beyond their scopes, to reduce the number of
manipulations of the stack pointer at run time.)
Temporaries needed across distinct statement boundaries usually
are associated with Fortran blocks (such as @code{DO}/@code{END DO}).
(Also, there might be temporaries not associated with blocks at all---these
would be in the scope of the entire program unit.)
Each Fortran block @emph{should} get its own block/scope in the GBE.
This is best, because it allows temporaries to be more naturally handled.
However, it might pose problems when handling labels
(in particular, when they're the targets of @code{GOTO}s outside the Fortran
block), and generally just hassling with replicating
parts of the @code{gcc} front end
(because the FFE needs to support
an arbitrary number of nested back-end blocks
if each Fortran block gets one).
So, there might still be a need for top-level temporaries, whose
``owning'' scope is that of the containing procedure.
Also, there seems to be problems declaring new variables after
generating code (within a block) in the back end, leading to, e.g.,
@samp{label not defined before binding contour} or similar messages,
when compiling with @samp{-fstack-check} or
when compiling for certain targets.
Because of that, and because sometimes these temporaries are not
discovered until in the middle of of generating code for an expression
statement (as in the case of the optimization for @samp{X**I}),
it seems best to always
pre-scan all the expressions that'll be expanded for a block
before generating any of the code for that block.
This pre-scan then handles discovering and declaring, to the back end,
the temporaries needed for that block.
It's also important to treat distinct items in an I/O list as distinct
statements deserving their own blocks.
That's because there's a requirement
that each I/O item be fully processed before the next one,
which matters in cases like @samp{READ (*,*), I, A(I)}---the
element of @samp{A} read in the second item
@emph{must} be determined from the value
of @samp{I} read in the first item.
@node Transforming DO WHILE
@subsection Transforming DO WHILE
@samp{DO WHILE(expr)} @emph{must} be implemented
so that temporaries needed to evaluate @samp{expr}
are generated just for the test, each time.
Consider how @samp{DO WHILE (A//B .NE. 'END'); @dots{}; END DO} is transformed:
@smallexample
for (;;)
@{
int temp0;
@{
char temp1[large];
libg77_catenate (temp1, a, b);
temp0 = libg77_ne (temp1, 'END');
@}
if (! temp0)
break;
@dots{}
@}
@end smallexample
In this case, it seems like a time/space tradeoff
between allocating and deallocating @samp{temp1} for each iteration
and allocating it just once for the entire loop.
However, if @samp{temp1} is allocated just once for the entire loop,
it could be the wrong size for subsequent iterations of that loop
in cases like @samp{DO WHILE (A(I:J)//B .NE. 'END')},
because the body of the loop might modify @samp{I} or @samp{J}.
So, the above implementation is used,
though a more optimal one can be used
in specific circumstances.
@node Transforming Iterative DO
@subsection Transforming Iterative DO
An iterative @code{DO} loop
(one that specifies an iteration variable)
is required by the Fortran standards
to be implemented as though an iteration count
is computed before entering the loop body,
and that iteration count used to determine
the number of times the loop body is to be performed
(assuming the loop isn't cut short via @code{GOTO} or @code{EXIT}).
The FFE handles this by allocating a temporary variable
to contain the computed number of iterations.
Since this variable must be in a scope that includes the entire loop,
a GBEL block is created for that loop,
and the variable declared as belonging to the scope of that block.
@node Transforming Block IF
@subsection Transforming Block IF
Consider:
@smallexample
SUBROUTINE X(A,B,C)
CHARACTER*(*) A, B, C
LOGICAL LFUNC
IF (LFUNC (A//B)) THEN
CALL SUBR1
ELSE IF (LFUNC (A//C)) THEN
CALL SUBR2
ELSE
CALL SUBR3
END
@end smallexample
The arguments to the two calls to @samp{LFUNC}
require dynamic allocation (at run time),
but are not required during execution of the @samp{CALL} statements.
So, the scopes of those temporaries must be within blocks inside
the block corresponding to the Fortran @code{IF} block.
This cannot be represented ``naturally''
in vanilla C, nor in GBEL.
The @samp{if}, @samp{elseif}, @samp{else},
and @samp{endif} constructs
provided by both languages must,
for a given @samp{if} block,
share the same C/GBE block.
Therefore, any temporaries needed during evaluation of @samp{expr}
while executing @samp{ELSE IF(expr)}
must either have been predeclared
at the top of the corresponding @code{IF} block,
or declared within a new block for that @code{ELSE IF}---a block that,
since it cannot contain the @code{else} or @code{else if} itself
(due to the above requirement),
actually implements the rest of the @code{IF} block's
@code{ELSE IF} and @code{ELSE} statements
within an inner block.
The FFE takes the latter approach.
@node Transforming SELECT CASE
@subsection Transforming SELECT CASE
@code{SELECT CASE} poses a few interesting problems for code generation,
if efficiency and frugal stack management are important.
Consider @samp{SELECT CASE (I('PREFIX'//A))},
where @samp{A} is @code{CHARACTER*(*)}.
In a case like this---basically,
in any case where largish temporaries are needed
to evaluate the expression---those temporaries should
not be ``live'' during execution of any of the @code{CASE} blocks.
So, evaluation of the expression is best done within its own block,
which in turn is within the @code{SELECT CASE} block itself
(which contains the code for the CASE blocks as well,
though each within their own block).
Otherwise, we'd have the rough equivalent of this pseudo-code:
@smallexample
@{
char temp[large];
libg77_catenate (temp, 'prefix', a);
switch (i (temp))
@{
case 0:
@dots{}
@}
@}
@end smallexample
And that would leave temp[large] in scope during the CASE blocks
(although a clever back end *could* see that it isn't referenced
in them, and thus free that temp before executing the blocks).
So this approach is used instead:
@smallexample
@{
int temp0;
@{
char temp1[large];
libg77_catenate (temp1, 'prefix', a);
temp0 = i (temp1);
@}
switch (temp0)
@{
case 0:
@dots{}
@}
@}
@end smallexample
Note how @samp{temp1} goes out of scope before starting the switch,
thus making it easy for a back end to free it.
The problem @emph{that} solution has, however,
is with @samp{SELECT CASE('prefix'//A)}
(which is currently not supported).
Unless the GBEL is extended to support arbitrarily long character strings
in its @code{case} facility,
the FFE has to implement @code{SELECT CASE} on @code{CHARACTER}
(probably excepting @code{CHARACTER*1})
using a cascade of
@code{if}, @code{elseif}, @code{else}, and @code{endif} constructs
in GBEL.
To prevent the (potentially large) temporary,
needed to hold the selected expression itself (@samp{'prefix'//A}),
from being in scope during execution of the @code{CASE} blocks,
two approaches are available:
@itemize @bullet
@item
Pre-evaluate all the @code{CASE} tests,
producing an integer ordinal that is used,
a la @samp{temp0} in the earlier example,
as if @samp{SELECT CASE(temp0)} had been written.
Each corresponding @code{CASE} is replaced with @samp{CASE(@var{i})},
where @var{i} is the ordinal for that case,
determined while, or before,
generating the cascade of @samp{if}-related constructs
to cope with @code{CHARACTER} selection.
@item
Make @samp{temp0} above just
large enough to hold the longest @code{CASE} string
that'll actually be compared against the expression
(in this case, @samp{'prefix'//A}).
Since that length must be constant
(because @code{CASE} expressions are all constant),
it won't be so large,
and, further, @samp{temp1} need not be dynamically allocated,
since normal @code{CHARACTER} assignment can be used
into the fixed-length @samp{temp0}.
@end itemize
Both of these solutions require @code{SELECT CASE} implementation
to be changed so all the corresponding @code{CASE} statements
are seen during the actual code generation for @code{SELECT CASE}.
@node Transforming Expressions
@section Transforming Expressions
The interactions between statements, expressions, and subexpressions
at program run time can be viewed as:
@smallexample
@var{action}(@var{expr})
@end smallexample
Here, @var{action} is the series of steps
performed to effect the statement,
and @var{expr} is the expression
whose value is used by @var{action}.
Expanding the above shows a typical order of events at run time:
@smallexample
Evaluate @var{expr}
Perform @var{action}, using result of evaluation of @var{expr}
Clean up after evaluating @var{expr}
@end smallexample
So, if evaluating @var{expr} requires allocating memory,
that memory can be freed before performing @var{action}
only if it is not needed to hold the result of evaluating @var{expr}.
Otherwise, it must be freed no sooner than
after @var{action} has been performed.
The above are recursive definitions,
in the sense that they apply to subexpressions of @var{expr}.
That is, evaluating @var{expr} involves
evaluating all of its subexpressions,
performing the @var{action} that computes the
result value of @var{expr},
then cleaning up after evaluating those subexpressions.
The recursive nature of this evaluation is implemented
via recursive-descent transformation of the top-level statements,
their expressions, @emph{their} subexpressions, and so on.
However, that recursive-descent transformation is,
due to the nature of the GBEL,
focused primarily on generating a @emph{single} stream of code
to be executed at run time.
Yet, from the above, it's clear that multiple streams of code
must effectively be simultaneously generated
during the recursive-descent analysis of statements.
The primary stream implements the primary @var{action} items,
while at least two other streams implement
the evaluation and clean-up items.
Requirements imposed by expressions include:
@itemize @bullet
@item
Whether the caller needs to have a temporary ready
to hold the value of the expression.
@item
Other stuff???
@end itemize