MAINSAIL Compiler User's Guide, Chapter 4

previous   next   top   contents   index   framed top   this page unframed


4. Compiler Subcommands

There are many subcommands available for use with the compiler. Subcommands affect the objmod and/or intmod generated for the compilation and the information that the compiler displays during the compilation. Subcommand mode is entered by terminating the input line typed to the compiler prompt with a comma.

When subcommand mode is entered, the subcommand prompt “>” is displayed. Any number of subcommands may be entered at this point, one per line. Subcommand mode is exited by typing <eol> to the > prompt.

Multiline subcommands may be entered by terminating each line except the last with a backslash (\). The backspace and following end-of-line are discarded, and all the lines entered are concatenated to form the subcommand.

File names in subcommands cannot contain space characters.

Valid subcommands are listed in Table 4–1. In this table, commands that do not have “(nonsticky)” in their description remain in effect for all subsequently compiled MODULEs until either another subcommand turns it off or the compiler exits (commands that perform a single, one-time-only action, such as ABORT and REDEFINE, are also nonsticky). Nonsticky subcommands apply only to the next MODULE compiled.

Any sticky subcommand may be made temporarily nonsticky by immediately following the subcommand (before any arguments) with an asterisk; e.g., NOGENCODE * indicates that object MODULE generation is to be omitted only for the next compilation.

XIDAK reserves the right to create compiler subcommands for internal use only. Such subcommands are not documented here and are subject to change and/or removal without notice. You should not use undocumented subcommands; their effects are undefined.

Compiler subcommands may change from release to release of MAINSAIL.

Mixed case is used in the subcommands to show the minimum permitted abbreviation of compiler subcommands. The uppercase portion of each compiler subcommand in mixed case is a sufficient abbreviation for that subcommand (as if the upperCase bit were given to cmdMatch).

Table 4–1. MAINSAIL Compiler Subcommands
Subcommand Description
ABORT Abort this compilation
ACheck Set default to emit code to catch arithmetic overflow, etc.
ACHECKALL ACHECK unconditionally
ALIST Allow disassembly
BROWSE Allow code browsing
Check Set default to emit code to catch subscript errors, etc.
CHECKALL CHECK unconditionally
CMDLINE s Add s to the end of the cmdLine list (nonsticky)
DATETIMECHECK Check date/time match when used as supporting intmod
DEBUG Make this MODULE debuggable, and turn on INCREMENTAL
FLDXREF {f} Write field cross reference {to file f (nonsticky)}
FLI s Generate code for foreign interface s
GENcode Generate code (i.e., produce objmod)
GENINLINES Generate bodies for inline PROCEDUREs
INCREMENTAL Allow output to be incrementally recompiled
ININTLIB f Input intmod is in library f
INOBJFILE f Input objmod is in file f (nonsticky)
INOBJLIB f Input objmod is in library f
ITFXREF {f} Write interface cross reference {to file f (nonsticky)}
LOG Show log info
MODTIME Measure time spent in this MODULE
MONITOR Turn on PER{MOD,PROC,STMT} and {MOD,PROC}TIME
OPtimize Set default to optimize all PROCEDUREs
OPtimize pi Optimize PROCEDUREs pi = p1 p2 ... pn (nonsticky)
OPTIMIZEALL Optimize all PROCEDUREs
OUTINTFILE f Output intmod to file f (nonsticky)
OUTINTLIB f Output intmod to library file f
OUTOBJFILE f Output objmod to file f (nonsticky)
OUTOBJLIB f Output objmod to library file f
PERMOD Count total statements executed in the MODULE
PERPROC Count total statements executed in each PROCEDURE
PERSTMT Count times each statement is executed
PLIST {f} Write parse tree listing {to file f (nonsticky if f specified)}
PROCCALLS {f} Write procedure calls {to file f (nonsticky)}
PROCS Show names of PROCEDUREs as they are parsed and generated
PROCTIME Measure time spent in each PROCEDURE
RECOMPILE pi Recompile PROCEDUREs pi = p1 p2 ... pn (nonsticky)
REDEFINE x y Do $GLOBALREDEFINE x = [y];
RESPONSE Get user response to error messages
RPC {C} generate code for remote PROCEDURE call {in C}
SAVEON {f} Create intmod containing all compiler info {save on file f}
SLIST {f} Write source listing {to file f (nonsticky)}
STRICTCLASSES Enforce strict class compatibility
SUBCOMMAND s Execute MAINEX subcommand s
TARGET s Generate for target system s
UCHECK Set default to catch uninitialized locals
UNBOUND Nonbound-invocation MODULE
# s A comment (s is ignored)
NOACheck Turn off ACHECK
NOACHECKALL Turn off ACHECKALL
NOALIST Turn off ALIST
NOBROWSE Turn off BROWSE
NOCheck Turn off CHECK
NOCHECKALL Turn off CHECKALL
NODATETIMECHECK Turn off DATETIMECHECK
NODEBUG Turn off DEBUG and INCREMENTAL
NOFLDXREF Turn off FLDXREF
NOGENcode Turn off GENCODE
NOGENINLINES Turn off GENINLINES
NOINCREMENTAL Turn off INCREMENTAL
NOININTLIB Turn off ININTLIB
NOINOBJLIB Turn off INOBJLIB
NOITFXREF Turn off ITFXREF
NOLOG Turn off LOG
NOMONITOR Turn off PER{MOD,PROC,STMT} and {MOD,PROC}TIME
NOOPtimize Turn off OPTIMIZE
NOOPtimize pi Do not optimize PROCEDURE(s) pi = p1 ... pn
NOOPTIMIZEALL Turn off NOOPTIMIZEALL
NOOUTINTLIB Turn off OUTINTLIB
NOOUTOBJLIB Turn off OUTOBJLIB
NOPLIST Turn off PLIST
NOPROCCALLS Turn off PROCCALLS
NOPROCS Turn off PROCS
NOREDEFINE Remove all global definitions
NOREDEFINE xi Remove global definition(s) of xi = x1 ... xn
NORESPONSE Turn off RESPONSE
NORPC Turn off RPC
NOSAVEON Turn off SAVEON
NOSLIST Turn off SLIST
NOSTRICTCLASSESTurn off STRICTCLASSES
NOUCHECK Turn off UCHECK
NOUNBOUND Turn off UNBOUND
Synonyms for compatibility with older versions of the compiler:
LIBRARY f Same as GENCODE, OUTOBJLIB f
OUTPUT {f} Same as GENCODE {, OUTOBJFILE f}
NOLIBRARY Same as NOOUTOBJLIB
NOOUTPUT Same as NOGENCODE

All of the compiler subcommands except the following may be invoked from MAINSAIL source text with the $DIRECTIVE directive, as described in Chapter 16 of the MAINSAIL Language Manual:

FLDXREF FLI ININTLIB ITFXREF PLIST PROCCALLS RECOMPILE RPC SLIST TARGET
NOFLDXREF NOININTLIB NOITFXREF NOPLIST NOPROCCALLS NOSLIST

The $DIRECTIVE directive is never sticky, i.e., never applies to more than one MODULE, even in the same compiler session.

4.1. Subcommands in Parameters File

The compiler can read default subcommands from the standard parameter file (e.g., in Version 16.20, v1620.prm).

The subcommands go in the parameter group, $COMPIL. For example, to set the default compiler subcommands to be DEBUG, ACHECK, and UCHECK (all of which are otherwise turned off by default), specify:

$GROUP $COMPIL

DEBUG
ACHECK
UCHECK

The parameters file mechanism is described in detail in Chapter 28 of the MAINSAIL Language Manual.

4.2. ABORT

ABORT aborts the current compilation while in subcommand mode. This is useful if you have given subcommands that you realize to be incorrect for the current compilation. It is also useful as a $DIRECTIVE directive if a condition occurs at compiletime that requires that a compilation be aborted (a similar effect can be achieved by using the MESSAGE directive with the error option; see Section 16.1 of the MAINSAIL Language Manual.

4.3. ACHECK/NOACHECK, ACHECKALL/NOACHECKALL

The ACHECK option enables the generation of extra code to detect arithmetic overflow in (LONG) INTEGER and (LONG) REAL operations. On some processors, no extra code is required to detect certain kinds of arithmetic overflow; on such machines, an overflow exception may be generated whether or not the ACHECK subcommand was in effect when the overflowing code was compiled. Where extra instructions are required to detect overflow, ACHECKed code may be significantly larger and slower.

NOACHECK turns the ACHECK option off. It suppresses the generation of extra instructions; it does not necessarily mean that arithmetic exceptions are not caught.

ACHECKALL and NOACHECKALL override ACHECK and NOACHECK directives in the source text of a MODULE. Arithmetic checking, and the subcommands and directives used to control it, are described in more detail in Chapter 16 of the MAINSAIL Language Manual.

4.4. ALIST/NOALIST

ALIST causes the compiler to put information into the intmod required if the disassembler is to be used to generate an intermixed source/code listing. The objmod is not affected.

NOALIST turns off ALIST.

4.5. BROWSE/NOBROWSE

The BROWSE subcommand causes the compiler to generate an intmod that contains a subset of the information generated by the DEBUG subcommand. The information is sufficient to allow the debugger to examine symbol declarations, but not enough to allow to it to step through the generated code.

Intmods produced with the BROWSE subcommand are sufficient for the debugger command !D (show where an identifier was declared); see Section 4.8 of the MAINDEBUG User's Guide for details.

4.6. CHECK/NOCHECK, CHECKALL/NOCHECKALL

CHECK causes the compiler to generate code that checks for runtime errors (the list of errors checked for is the same as the list governed by the MAINSAIL language CHECK directive; consult Section 16.3 of the MAINSAIL Language Manual for details). This option should be used when debugging and testing programs. Once a program is debugged, it can be compiled NOCHECK to reduce code size and increase execution speed.

NOCHECK turns off CHECK.

CHECKALL and NOCHECKALL override CHECK and NOCHECK directives in the source text of a MODULE. The rules for checking, and the subcommands and directives used to control it, are described in more detail in Section 16.3 of the MAINSAIL Language Manual.

4.7. CMDLINE s

CMDLINE s concatenates the STRING:

s & eol

to the end of the current cmdLine STRING. Whenever the compiler needs to read a line from file cmdFile, it first checks whether cmdLine is non-Zero, and if so, it reads the line from cmdLine rather than cmdFile. For example, interactive defines may use cmdLine. Thus, responses to interactive defines can be specified in CMDLINE subcommands. This is sometimes useful in compilation scripts; e.g., if a compilation may or may not do a single interactive define (based on compiletime evaluation), the response can be put in a CMDLINE subcommand so that the compilation will complete correctly even if the interactive define does not occur.

4.8. DATETIMECHECK/NODATETIMECHECK

The DATETIMECHECK subcommand controls whether MAINSAIL checks the date and time of compilation recorded in a supporting intmod when it opens the intmod.

DATETIMECHECK is mainly intended to be used as a compiler directive in a MODULE's source code, rather than interactively as a compiler subcommand. It is described in more detail in Section 16.4.2 of the MAINSAIL Language Manual.

4.9. DEBUG/NODEBUG

DEBUG causes the compiler to put information into the intmod that is used by the MAINSAIL debugger. A MODULE that is to take part in debugging must be compiled with this option; see Section 2.1 of the MAINDEBUG User's Guide for more information. DEBUG slightly increases the size and execution time of the objmod.

PROCEDUREs declared INLINE (but not $ALWAYSINLINE) are not expanded inline if DEBUG is in effect. PROCEDUREs declared $ALWAYSINLINE are expanded inline even if DEBUG is in effect. Thus, a MODULE that uses INLINE PROCEDUREs may be larger and slower for this reason also.

NODEBUG turns off DEBUG.

As a side effect, DEBUG sets the INCREMENTAL and GENINLINES options, and NODEBUG clears them. DEBUG * has no effect on the current sticky subcommand setting values used in subsequent compilations, and may therefore be more suitable for compilation scripts in which both debuggable and non-debuggable MODULEs are compiled.

4.10. FLDXREF/FLDXREF f/NOFLDXREF

The FLDXREF and FLDXREF f options are similar to the corresponding ITFXREF options, except that they cause field references of the form p.f, where p is a POINTER or ADDRESS variable, to be listed (ITFXREF is for m.f only where m is a MODULE name). CLASS names enclosed in angle brackets are listed in place of the MODULE names for the ITFXREF option. Both ITFXREF and FLDXREF can be specified; the output goes to the same listing file if no output file is specified for either (.xrf file), or if the same output file is specified for both.

The interface cross-reference merger, XRFMRG, is used in conjunction with the ITFXREF and FLDXREF compiler subcommands. It is described in Chapter 6.

Figure 4–2. FLDXREF Sample Output
Field Cross-Reference for MODULE TOPCMP

<
$DEVICECLS>.$DEVNEWBUF       (m:syslibSFWRITE 13.13
<
$MICONF>.$CONFBITS           (m:tops20STTYWRITE 4.8
<
FILE>.$DEVICE                (m:syslibSFWRITE 13.11
                              13.13
      .
$REMSIZE               (m:syslibSFWRITE 13.13
                              13.16*
      .
$STATUSBITS            (m:syslibSFWRITE 13.8
                              13.16*
<
SYMBOL>.LINK                 (miscPFCOMPILE 5.96 5.100
<
TEXTFILE>.$NEXTTEXT          (m:syslibSFWRITE 13.15*

4.11. FLI s

The FLI s subcommand specifies the direction and calling conventions of a foreign MODULE interface compilation. The STRING s has the form xy, where x is a character indicating the direction of the FLI compilation and y is a character indicating the foreign language. FLI ? displays a list of valid xy combinations. The supported values for x and y are shown in Table 4–3 (undocumented values are not supported).

Table 4–3. The Format of Arguments to the Compiler FLI Subcommand
x Description y Description
T To foreignLanguage C the language C
F From foreignLanguage S Solaris C

Thus, TC means “To C (from MAINSAIL)”; FS means “From Solaris C (to MAINSAIL)”.

The C calling convention indicator is used for the C calling convention on most platforms. On operating systems where more than one C calling convention is supported, however, an alternative letter must be used to specify the convention in question.

You must specify the TARGET subcommand in conjunction with the FLI subcommand if the target is different than the host. Not every calling convention is implemented for every target. If a nonexistent or unavailable combination is selected, the compiler issues an error message to the effect that it cannot open the FLI code generator MODULE, the name of which is formed from the target, x, and y. Details on supported FLIs may be found in the relevant sections of the appropriate system-specific MAINSAIL documentation. If you need a complete, up-to-date list of the FLI code generators that have been implemented, please contact XIDAK.

FLI<eol> (i.e., no argument specified) turns off the FLI subcommand.

4.12. GENCODE/NOGENCODE

GENCODE specifies that an objmod is to be generated.

NOGENCODE specifies that no objmod is to be generated. This is useful for verifying that the syntax of a MODULE is correct, or for a MODULE for which just the intmod is desired.

4.13. GENINLINES/NOGENINLINES

GENINLINES specifies that bodies are to be generated for each INLINE PROCEDURE, though calls to INLINE PROCEDUREs are still expanded inline. This option is useful when debugging to make PROCEDUREs declared $ALWAYSINLINE callable from the debugger.

If some additional PROCEDURE bodies are generated due to this option, the objmod is larger.

DEBUG sets this option, and NODEBUG clears it, so it is rarely useful to use GENINLINES and NOGENINLINES explicitly (though they could be used to force code to be generated for an INLINE PROCEDURE for which a disassembly was to be obtained in order to examine the generated code).

NOGENINLINES turns off GENINLINES.

4.14. INCREMENTAL/NOINCREMENTAL

INCREMENTAL specifies that the intmod is to contain all the information required to support incremental recompilation. This subcommand must be given if the MODULE is ever to be incrementally recompiled. The objmod is not affected.

DEBUG sets this option, and NODEBUG clears it.

NOINCREMENTAL turns off INCREMENTAL.

4.15. ININTLIB f/NOININTLIB

ININTLIB f specifies that the input intmod is in the intlib f. This information is used during an incremental recompilation where just the MODULE name, say FOO, is given to the compiler prompt, and FOO resides in the intlib f. As a side effect, the intlib f remains open for further intmod searches.

NOININTLIB turns the ININTLIB option off, so that the default intmod search rules are subsequently followed.

4.16. INOBJFILE f

INOBJFILE f specifies that the object MODULE being recompiled is in the file f. This option is useful only when recompiling, since the compiler must then find the objmod for the MODULE being recompiled. This option need not be given if the objmod is in a file with the default objmod file name, or is in an open objmod library.

There is no corresponding ININTFILE subcommand, since the name of the input intmod file can be specified in response to the compiler prompt. If the intmod file has the default name, then the MODULE name can be given in response to the compiler prompt, and the compiler automatically finds the intmod file (and the objmod file if it also has the default name or is in an open objmod library).

4.17. INOBJLIB f/NOINOBJLIB

INOBJLIB f specifies that the input objmod is in the objmod library f. This information is used during an incremental recompilation, since the compiler must locate the objmod for the MODULE being recompiled. As a side effect, the objmod library f remains open for further objmod searches.

NOINOBJLIB turns the INOBJLIB option off, so that the default objmod search rules are subsequently followed.

4.18. ITFXREF/ITFXREF f/NOITFXREF

ITFXREF and ITFXREF f cause the compiler to generate an interface field cross-reference listing that gives the file, name of containing PROCEDURE, page, and line of every occurrence of an interface field referenced (both implicitly and explicitly) by the MODULE being compiled. In addition, an asterisk (*) indicates that a reference alters the (data) field. PROCEDURE and data fields as well as the MODULE's references to its own interface fields are reported. A field f referenced using p.f, where p is a POINTER variable rather than a MODULE name, is not included in the listing. Use the FLDXREF option, described in Section 4.10, to include such references.

If the file name for the cross-reference listing is not specified, the output is written to a file m.xrf, where m is the name of the MODULE being compiled.

Once the ITFXREF option is specified, it remains in effect until either the NOITFXREF option is specified or the compiler is exited. The ITFXREF f option does not remain in effect for subsequently compiled MODULEs.

Figure 4–4 is a sample cross-reference listing. At the left is an alphabetic list of module.field, where module is the name of the referenced MODULE and field is the name of the referenced field. The module part is specified only the first time so that references to the same MODULE stand out as a group.

At the right are the source file, name of the containing PROCEDURE, page and line occurrences of each reference to the corresponding field, and asterisk if the field is altered (e.g., assigned to) by the reference. The source file name is enclosed in parentheses and given before all references in that file. References are listed in the order encountered by the compiler. The name of the containing PROCEDURE is repeated only as often as necessary; i.e., it applies to all following items up to the next time a PROCEDURE name is given. SOURCEFILE directives and implicit sourcefiles due to FORWARD PROCEDUREs can cause more than one source file to appear in the right-hand column.

Figure 4–4. ITFXREF Sample Output
Interface Cross-Reference for MODULE TOPCMP

COMPIL.COMPILEBITS        (miscPFCOMPILE 5.13 5.24* 5.25
                          5.53 5.54 5.60* 
SUBCOMMAND 41.43
                          41.47* 41.49* 41.50* 41.51*
                          41.54* 41.55* 41.56* 41.57*
                          41.60* 41.61* 41.62* 41.63*
      .
COMPVERSIONBITS    (miscPFCOMPILE 5.15 5.16
      .
SYSVERSIONBITS     (miscPFCOMPILE 5.18 5.19
      .
TARGETSYSTEM       (miscPFCOMPILE 5.56 5.57
PASS1.FIRSTPASS           (miscPFCOMPILE 5.63
PASS2.SECONDPASS          (miscPFCOMPILE 5.75
TOPCMP.COMMANDSTRING      (miscPFCMPREAD 3.8*
                          
PROGCOMPILE 35.8*
      .
DISPOSEDSYMLIST    (miscPFCOMPILE 5.47* 5.95
      .
ENCODELIST         (miscPFCOMPILE 5.44* 5.99
                          5.100* 5.100
      .
ERRFILE            (miscPFCOMPILE 5.30 5.30*
      .
ERRS               (miscPFCOMPILE 5.31* 5.68
                          5.76* 
PROGCOMPILE 35.12

4.19. LIBRARY f/NOLIBRARY

LIBRARY f is equivalent to the two options GENCODE and OUTOBJLIB f.

NOLIBRARY is equivalent to NOOUTOBJLIB.

4.20. LOG/NOLOG

The LOG option causes the compiler to display file names, pages, and PROCEDURE names (for FORWARD PROCEDUREs) during compilation.

NOLOG turns off LOG.

4.21. MODTIME

MODTIME specifies that the objmod be configured so that it can monitor the total (deep and shallow) time spent in the MODULE. The MODULE must be run under the MAINSAIL performance monitor (MAINPM) to obtain the monitored value (see Table 3–2 of the MAINPM User's Guide).

NOMONITOR turns off all monitor options.

4.22. MONITOR/NOMONITOR

MONITOR is a quick way to specify all the performance monitoring subcommands: PERMOD, PERPROC, PERSTMT, MODTIME, and PROCTIME.

NOMONITOR turns off all monitor options.

4.23. OPTIMIZE/NOOPTIMIZE, OPTIMIZE procedurei/NOOPTIMZE procedurei, and OPTIMIZEALL/NOOPTIMIZEALL

OPTIMIZE tells the compiler to produce code that executes faster in many situations. The exact optimizations performed are machine-dependent. In some cases, optimized code may be identical to unoptimized code; in other cases, it may run substantially faster.

OPTIMIZE may take an argument list of PROCEDURE names, i.e., OPTIMIZE procedure1 procedure2 ... proceduren. In this form, the specified PROCEDUREs are optimized whether or not the rest of the MODULE is optimized. This form is non-sticky.

NOOPTIMIZE turns off the OPTIMIZE option. NOOPTIMIZE may also take a list of PROCEDUREs that are not to be optimized, whether or not the rest of the MODULE is optimized. If a PROCEDURE is specified in both OPTIMIZE and NOOPTIMIZE subcommands, the last reference takes precedence.

OPTIMIZEALL and NOOPTIMIZEALL override OPTIMIZE and NOOPTIMIZE directives in the source text of a MODULE. The rules for optimization, and the subcommands and directives used to control it, are described in more detail in Chapter 17 of the MAINSAIL Language Manual.

4.24. OUTINTFILE f

OUTINTFILE f specifies that the intmod is to be stored as the file f. The intmod is by default stored in a file the name of which is derived from the MODULE name, unless an OUTINTLIB subcommand is specified, in which case the intmod is stored in the specified intmod library. OUTINTFILE overrides NOOUTINTLIB for the current compilation.

4.25. OUTINTLIB f/NOOUTINTLIB

OUTINTLIB f specifies that the intmod is to be stored in the intmod library f. The intlib subsequently remains open.

NOOUTINTLIB turns off OUTINTLIB.

4.26. OUTOBJFILE f

OUTOBJFILE f specifies that the objmod is to be stored as the file f. The objmod is by default stored in a file with a name derived from the MODULE name, unless an OUTOBJLIB subcommand is specified, in which case the objmod is stored in the specified objmod library.

4.26.1. OUTOBJFILE Command Can Specify RPC Output File Names

When the RPC subcommand is specified, the compiler produces two output files, the client stub and the server stub. Since it would not make sense for both to have the same name, the compiler treats the OUTOBJFILE command specially when RPC is in effect.

When RPC is in effect, the name given to the OUTOBJFILE subcommand is decomposed into its parts. The name of the generated source file for the client stub is obtained by appending cli to the base of the given file name and then recomposing the file name; the name of the generated source file for the server stub is obtained by appending srv to the base and then recomposing the file name. This allows the OUTOBJFILE subcommand to be used, for example, to specify that the generated files be written to a different directory.

For example, if you compile a MODULE FOOBLE in a file fooble.ms, and want to have the output on blarkcli.ms and blarksrv.ms in the directory ../ranmod instead of the default (fooblecli.msl and fooblesrv.msl on the current directory), you would specify:

compile (? for help): fooble.ms<eol>,
rpc<eol>
outobjfile ../ranmod/blark.ms<eol>
<eol>

4.27. OUTOBJLIB f/NOOUTOBJLIB

OUTOBJLIB f specifies that the objmod is to be stored in the objmod library f.

If for any reason the MODULE cannot be added to the specified library, the compiler prompts for an output file name.

The compiler uses the current TARGET subcommand value to determine the format of the target MODULE library.

NOOUTOBJLIB turns off OUTOBJLIB.

4.28. OUTPUT/OUTPUT f/NOOUTPUT

OUTPUT is the same as GENCODE, OUTPUT f is the same as GENCODE followed by OUTOBJFILE f, and NOOUTPUT is the same as NOGENCODE.

4.29. PERMOD

PERMOD specifies that the objmod be configured so that it can monitor the total number of statements executed in the MODULE. The MODULE must be run under the MAINSAIL performance monitor (MAINPM) to obtain the monitored value (see Table 3–2 of the MAINPM User's Guide).

NOMONITOR turns off all monitor options.

4.30. PERPROC

PERPROC specifies that the objmod be configured so that it can monitor the total number of statements executed in each PROCEDURE. The MODULE must be run under the MAINSAIL performance monitor (MAINPM) to obtain the monitored values (see Table 3–2 of the MAINPM User's Guide).

NOMONITOR turns off all monitor options.

4.31. PERSTMT

PERSTMT specifies that the objmod be configured so that it can monitor the total number of times each statement is executed. The MODULE must be run under the MAINSAIL performance monitor (MAINPM) to obtain the monitored values (see Table 3–2 of the MAINPM User's Guide).

NOMONITOR turns off all monitor options.

4.32. PLIST/PLIST f/NOPLIST

The PLIST subcommand causes a parse tree listing to be written to the specified file (in the PLIST f form) or to a file formed from the MODULE name and the extension pls. The parse tree listing is a “decompiled” form of each PROCEDURE's body. This listing may be useful for files that call complicated macros or include complicated conditional compilation; the PLIST listing lets you see just how they were processed at compiletime to produce the PROCEDURE bodies the compiler actually compiled.

4.33. PROCCALLS/PROCCALLS f/NOPROCCALLS

Temporary feature: subject to change

Some users have requested tools to help analyze the static PROCEDURE call structure of a MAINSAIL program.

The MAINSAIL compiler subcommand:

PROCCALLS {f}   write proc calls {to file f (nonsticky)}

causes the compiler to create a human-readable text file with name f that contains, for each PROCEDURE body parsed during the compilation, a list of all the PROCEDUREs it calls directly. If f is omitted, the created file has the name moduleName.prc, where moduleName is the name of the compiled MODULE.

The PROCCALLS subcommand is sticky if f is omitted, but can be turned off using the subcommand:

NOPROCCALLS     turn off PROCCALLS

The output file is generated during the compiler's first pass so that it can be obtained even if code is not generated, e.g., if a syntax error is detected or if the compiler subcommand NOGENCODE is in effect.

The output format described here is subject to change based on user feedback. Any program that parses this output should be written so it can be easily modified.

The intention of PROCCALLS files is to support a program that reads all of the PROCCALLS files for a “system”, builds a data structure that represents all the calls, then displays or answers questions about the static call chains. Such an analysis program is not currently provided by XIDAK.

At present, a PROCCALLS file consists of:

The pages are separated by end-of-page characters (ASCII form feed).

4.33.1. Header Page

The header page is the first page of the file. Its first line is:

ProcCalls for m

where m is the name of the compiled MODULE. More lines may be added to this page, so skip to end-of-page (or end-of-file) to process the remainder of the file.

4.33.2. CLASS Page

The CLASS page is present if the MODULE is declared with a prefix CLASS, e.g., MODULE(cls) foo. The CLASS page can occur as any page after the header page; it is output when the MODULE declaration is encountered or when an intmod that contains the MODULE's declaration is made visible (e.g., using RESTOREFROM). It will often be the second page since a MODULE declaration is usually given before any PROCEDURE bodies.

A CLASS page consists of one or more header lines, a blank line and one or more CLASS names:

Module m prefix classes
possible additional header lines

c1
...
cn

The first header line has the format Module m prefix classes, where m is the name of the compiled MODULE. Additional header lines may be added in the future.

c1 is the name of the immediate prefix CLASS of the MODULE, e.g., cls in the example above. If c1 was declared with a prefix CLASS, then the name of that CLASS is given on the next line, and so forth, until a CLASS cn is reached that was not declared with a prefix CLASS.

This CLASS information can be used to determine which PROCEDUREs can possibly be called from a PROCEDURE call of the form p.f, where p is a POINTER of some CLASS c. As described below, a p.f call is indicated on a call page as <c>.f, where c is f's CLASS. To determine all m.f's that could be the actual target of such a call, where m is a MODULE name, examine all the PROCCALLS files of interest to find those MODULEs whose CLASS page indicates that c is a prefix CLASS of the MODULE. Note that this approach can fail if two different interface CLASSes are declared with the same name.

Note that a MODULE can have an interface PROCEDURE, but no prefix CLASS, as in MODULE m (PROCEDURE foo). Such a MODULE cannot legitimately be the target of a p.foo call where p is a POINTER, since there is no legal way to classify p as having m's interface. The programmer could, in the current version of MAINSAIL, declare CLASS c (PROCEDURE foo) and POINTER(c) p, then use p := new(m); p.foo, but this is not supported and may not work in future versions of MAINSAIL (MODULE(c) m should have been used for m's declaration). The <c>.foo in the call page described below is not helpful in detecting a potential call to such an m.foo.

4.33.3. Call Page

A call page consists of one or more header lines, a blank line, and a possibly empty list of called PROCEDUREs. An example of a call page is:

Procedure INITIALPROC
Declared at pass1.msl 8.11 (1318)

$ERRMOD.
ERRMSG
$KERMOD.$CLASSDSCRFOR
$KERMOD.$NEWAREA
$KERMOD.NEWRECORD
$KERMOD.SNEWDATASECTION
$SYS$$SEARCHCALLCHAIN
$UTYMOD.$SCANSET
<
COMPILCLS>.ALLOCATEKEPTSCRATCHSPACE
<
TREEIOCLS>.INITTREEIO

The first header line has one of the following formats:

The second header line indicates where the PROCEDURE body was declared. It has the format Declared at fn p.rl (ap), where fn is the file name, p is the page number, rl is the relative line number on the page, and ap is the absolute line number.

A called PROCEDURE has one of the following forms:

The called PROCEDUREs are listed one per line in alphabetically ascending order based on the entire form just described. A PROCEDURE call form is listed for a given PROCEDURE just once even though the PROCEDURE may have been called many times. If an interface PROCEDURE f is called both as m.f and p.f for a MODULE m and POINTER p, it is listed twice, once as m.f and once as <c>.f as described above. A call to an {$ALWAYS}INLINE PROCEDURE is treated just like any other call; i.e., the fact that the called PROCEDURE was declared as {$ALWAYS}INLINE is ignored as far as the listing file is concerned. If a PROCEDURE calls itself, its call list will contain an instance of itself.

4.33.4. Example

An example of a short PROCCALLS file follows:

-------------------- start of file ---------------------
ProcCalls for PASS1
------------------------- 
eop --------------------------
Module PASS1 prefix classes

PASS1CLS
------------------------- 
eop --------------------------
Procedure INITIALPROC
Declared at pass1-14-10.msl 8.11 (1318)

$ERRMOD.ERRMSG
$KERMOD.$CLASSDSCRFOR
$KERMOD.$NEWAREA
$KERMOD.NEWRECORD
$KERMOD.SNEWDATASECTION
$SYS$$SEARCHCALLCHAIN
$UTYMOD.$SCANSET
<
COMPILCLS>.ALLOCATEKEPTSCRATCHSPACE
<
TREEIOCLS>.INITTREEIO
------------------------- 
eop --------------------------
Procedure FINALPROC
Declared at pass1-14-10.msl 8.85 (1392)

$KERMOD.$DISPOSEAREA
$KERMOD.PDISPOSE
$UTYMOD.$ISCANREL
FINALSTRMATH
------------------------- 
eop --------------------------
Procedure ADDSYMTBLNODETOLIST
Declared at pass1-14-10.msl 9.5 (1406)

$KERMOD.NEWRECORD
<
INTMGRCLS>.GETMODULEINDEX
<
INTMGRCLS>.OPENSYMTBLNODE
CMPHDR$FINDFILENAME
CMPHDR$GETFILENUM
------------------------- 
eop --------------------------
Procedure APPENDTEXT
Declared at pass1-14-10.msl 10.1 (1448)

$SYS$$CSCAN
------------------------- 
eop --------------------------
Procedure CHECKFORTHISMODULEDCL
Declared at pass1-14-10.msl 11.1 (1456)

$TXTDIO.LISREAD
<
INTMGRCLS>.GETMODULEINDEX
ERR
FINDSYMBOL
SETOWNERMODULE
------------------------- 
eop --------------------------
Procedure <PASS1CLS>.COMPILEDECLARATIONS
Declared at pass1-14-10.msl 12.1 (1489)

$KERMOD.$RAISE
DEINITCOMPILEDECLARATIONS
GETDCLS
INITCOMPILEDECLARATIONS
POSTCOMPILE
SCANNER
------------------------- 
eop --------------------------
Procedure POPLINE
Declared at pass1-14-10.msl 80.1 (4398)

--------------------- 
end of file ----------------------

4.34. PROCS/NOPROCS

PROCS causes the names of PROCEDUREs to be printed when their bodies are compiled. The PROCEDURE names are normally printed twice: once during the first pass, and once during code generation (unless the PROCEDURE has no body, as is typically the case for an INLINE PROCEDURE). During the first pass, the message Compiling PROCEDURE procedureName is written to logFile; during code generation, the message Generating code for PROCEDURE procedureName is written.

If the PROCS option is not given, there is normally no output to logFile from the compiler during the code generation phase. This option allows the user to monitor the progress of the code generator, which is useful when the compiler gets a fatal error (such as running out of memory) while compiling a MODULE. The MODULE can be compiled with the PROCS option to determine which PROCEDURE caused the problem.

NOPROCS turns off PROCS.

4.35. PROCTIME

PROCTIME specifies that the objmod be configured so that it can monitor the total (deep and shallow) time spent in each PROCEDURE. The MODULE must be run under the MAINSAIL performance monitor (MAINPM) to obtain the monitored values (see Table 3–2 of the MAINPM User's Guide).

NOMONITOR turns off all monitor options.

4.36. RECOMPILE procedure1 procedure2 ... proceduren

RECOMPILE procedure1 procedure2 ... proceduren indicates that an incremental recompilation is to be done, and that the PROCEDUREs procedure1, procedure2, and so on through proceduren are to be recompiled. (initialProc and finalProc are the names of unnamed INITIAL and FINAL PROCEDUREs.) The effect is undefined if changes have been made to any of the MODULE's source text outside any of the specified PROCEDUREs procedurei.

The compiler finds the intmod for the MODULE being recompiled, and finds within it the file and starting position of each of the PROCEDUREs procedurei. It then compiles them in the order in which their bodies were originally encountered, automatically compensating for a change in the size of each PROCEDURE if it affects the location of another PROCEDURE later in the same file. The compiler complains if the expected PROCEDURE header(s) are not found at the expected position(s).

If code is being generated, it is generated just for the recompiled PROCEDUREs. The old objmod must be located. The newly generated code is appended to the end of the old objmod, and the replaced code becomes wasted space. Similarly, the new intmod information is appended to the end of the old intmod, and the replaced information becomes wasted space. Thus, the intmod and objmod are larger than if a full compilation were done, though the compilation takes less time.

As described more fully in Chapter 3, many options are restored from the old intmod, and the presently specified settings ignored. Options that do not affect global attributes of the intmod or objmod can be altered, e.g., LOG/NOLOG.

4.37. REDEFINE id def/NOREDEFINE/NOREDEFINE defi

REDEFINE x y is equivalent to compiling the following global definition at the start of the compilation:

$GLOBALREDEFINE x = [y];

y is the text that remains (if any) after removing blank space after x and from the end of the command line. $GLOBALREDEFINE is described in Section 16.7 of the MAINSAIL Language Manual. It defines identifiers that can be referenced across all compilations in a given invocation of the compiler.

The first argument to the compiler's REDEFINE subcommand must be a simple macro identifier; the macro cannot have parameters. Thus, the subcommand:

REDEFINE mac(parm) body<eol>

causes the compiler to issue an error message.

NOREDEFINE deletes all global definitions. NOREDEFINE x1 x2 ... xn deletes the global definitions for the identifiers x1, x2, ..., xn.

The nonsticky indicator (*) has no effect on these subcommands; they are inherently sticky.

4.38. RESPONSE/NORESPONSE

The NORESPONSE option means “Do not get a user response to error messages”. The message is reported and compilation continues (unless the error is fatal). This is especially useful for running the compiler in “batch” mode, i.e., when no user is present to respond to any error messages. If a fatal error occurs while NORESPONSE is in effect, a stack dump is written to logFile and MAINSAIL exits.

NORESPONSE turns off RESPONSE. “RESPONSE” is equivalent to “SUBCOMMAND RESPONSE”, “NORESPONSE” to “SUBCOMMAND NORESPONSE”.

These options apply to all errors, not just those generated by the compiler, and remain in effect after exiting the compiler. Use the MAINEX subcommands RESPONSE and NORESPONSE outside the compiler to restore the previous option, if desired.

4.39. SAVEON/SAVEON f/NOSAVEON

SAVEON directs the compiler to put the information into the intmod that is needed to support the ability to open the MODULE during a later compilation, e.g., using the RESTOREFROM directive as described in Section 13.3 of the MAINSAIL Language Manual. Opening a MODULE makes the symbols and PROCEDURE bodies declared in the MODULE available.

SAVEON f is equivalent to SAVEON followed by OUTINTFILE f.

NOSAVEON turns off SAVEON.

4.40. SLIST/SLIST f/NOSLIST

SLIST f causes the compiler to generate a source listing on the file f in which macros are expanded and source text not compiled due to conditional compilation logic is omitted. f may be omitted, in which case the output file is formed from the MODULE name and the extension lst.

NOSLIST turns off SLIST.

4.41. STRICTCLASSES/NOSTRICTCLASSES

The compiler subcommand STRICTCLASSES can be used to cause the compiler to generate an error message for:

No error message is generated if either of the two POINTERs in question is unclassified.

In each of the cases mentioned above, the compiler does not have sufficient information to determine that the assignment is safe. For example, given the following declarations:

CLASS c1 (INTEGER i);
CLASS(c1c2 (INTEGER j);
POINTER(c1c1p;
POINTER(c2c2p;

then the assignment:

c1p := c2p;

is clearly safe, since a record of c2 will have all the fields of c1, but:

c2p := c1p;

is not necessarily safe, since c1p may legally point to a record of c1 instead of c2 (or to a record of any other CLASS derived from c1); in this case, the field j of c2 will not be present, but the compiler would permit the use of the field variable c2p.j.

It is this second kind of assignment that is flagged as an error when STRICTCLASSES is in effect.

Classification of POINTERs can still be specified by the programmer using the pointer:className syntax. Thus, to get the effect of the second assignment above when STRICTCLASSES is in effect, use:

c2p := c1p:c2;  # I know c1p really points to a c2 record

NOSTRICTCLASSES, which turns off STRICTCLASSES, is the default.

STRICTCLASSES is useful in conjunction with the GENERIC mechanism where it is desirable to invoke different PROCEDURE for POINTERs to different CLASSes derived from a common prefix CLASS. This effect cannot be achieved when STRICTCLASSES is not in effect. For example, given the declarations above, and:

PROCEDURE c1Proc (POINTER(c1c1p);
write(logFile,"c1Proc" & eol);

PROCEDURE c2Proc (POINTER(c2c2p);
write(logFile,"c2Proc" & eol);

GENERIC PROCEDURE proc "c2Proc,c1Proc";

the following code:

proc(c1p);
proc(c2p);

prints:

c1proc
c2proc

under STRICTCLASSES, but:

c2proc
c2proc

under NOSTRICTCLASSES.

For this kind of GENERIC PROCEDURE to work, STRICTCLASSES must be in effect at the point of call of the GENERIC PROCEDURE; it is not sufficient (or necessary) for it to be in effect at the point of declaration of the GENERIC PROCEDURE or any of the GENERIC PROCEDURE's instance PROCEDUREs. It may be useful to specify STRICTCLASSES as a $DIRECTIVE directive to ensure that it is turned on at the point of call of the GENERIC PROCEDURE.

4.42. SUBCOMMAND s

SUBCOMMAND s causes s to be executed as a MAINEX subcommand. For example, to open an intlib foo during a compilation, issue the subcommand SUBCOMMAND OPENINTLIB foo.

4.43. TARGET s/NOTARGET

TARGET s specifies that code is to be generated for the target system s, where s is a target system abbreviation (case is ignored). TARGET ? displays a summary of the system abbreviations. For example, to compile for PA-RISC UNIX (while running on some other operating system), use TARGET upa.

NOTARGET is the same as TARGET hostSystem; i.e., further compilations generate code for the host system.

Code generators for cross-compilation are separate products not shipped with a standard development system. Attempting to cross-compile to a system for which no code generator is available generates an error message saying that the required code generator cannot be found. Code generators for any system on which MAINSAIL is supported may be purchased from XIDAK.

4.44. UCHECK/NOUCHECK

The UCHECK command performs uninitialized variable checking.

The MAINSAIL compiler can detect at compiletime some cases where a local variable is certainly uninitialized when used. By default, the compiler issues a message at compiletime for such variables even when UCHECK is not in effect. In addition, if UCHECK is in effect, the compiler issues compiletime messages for all variables that might possibly be uninitialized when used.

The UCHECK and NOUCHECK subcommands also govern the generation of extra code to check for uses of uninitialized local variables (the compiler generates the checking code whether it is certain that the variable is uninitialized, or whether it just thinks it might be uninitialized). If a local variable is used before having been initialized, the extra code causes a runtime error to occur at the point the variable is used. The text of the error message includes the uninitialized variable's name.

The runtime error for uninitialized variables is not fatal, so that you may continue from such errors. The uninitialized variable is initialized to Zero before the error is reported, so that future references to the variable within the same PROCEDURE activation will not cause more errors. However, future references to the variable in subsequent PROCEDURE activations will cause more errors, one for each activation that uses the variable when it is uninitialized.

If your program was compiled debuggable, then you can set the uninitialized variable to any arbitrary value, not just Zero, by invoking the debugger and using the debugger's xs command. However, you must do this manually at each error.

UCHECK causes the compiler to generate the extra compiletime warnings and/or checking code, and NOUCHECK turns off UCHECK. The most recently specified UCHECK or NOUCHECK subcommand during a MODULE's compilation governs the generation of checking code for the entire MODULE. UCHECK may be specified only at the MODULE level; there is no way to turn it on or off for individual PROCEDUREs.

4.44.1. UCHECK Details

Occasionally, the compiler is unable to determine whether or not a local variable has been initialized when it is used at a particular place. In practice, most such local variables are, in fact, initialized, but the compiler's analysis is too primitive to detect this. For example, in the following code, the compiler would consider the local variable x to be possibly uninitialized when it was used in the statement x .+ n, even though the logic of the code is such that x will have always been initialized by the time it is used:

firstTime := TRUE;
DO  IF firstTime THENB x := 0; firstTime := FALSE END
    
EL x .+ n
UNTIL n .- 1 LEQ 0;

Despite its primitive nature, the compiler's analysis is sufficient to allow it to omit the extra UCHECK code for most local variables, since the compiler usually determines that most variables have been previously initialized everywhere they are used.

If UCHECK is in effect, the compiler reports at compiletime all local variables that are used when they are possibly uninitialized. It does this by writing messages to logFile, similar to the way it generates messages about local variables that it is sure are uninitialized when they are used. The extra variables are reported in order to inform the user of the variables for which extra checking code was generated, so that the user can modify the program so as to eliminate any chance of the errors actually occurring.

If NOUCHECK is in effect, the compiler does not report the local variables that are used when they are possibly uninitialized, because the list could, for some MODULEs, contain dozens of variables, most of which would always be initialized by the time they were used.

Except for USES and MODIFIES parameters, all local variables of data types other than POINTER, STRING, $PROCVAR, and inplace record and ARRAY are assumed to be uninitialized at the start of a PROCEDURE. A variable is officially considered to be initialized only by means of MAINSAIL constructs that are documented as having the effect of modifying a variable's value. Such constructs include assignments and passing a variable as a PRODUCES argument in a PROCEDURE call. In fact, the compiler may sometimes generate code at the start of a PROCEDURE to assign Zero to certain local variables, but the circumstances under which this occurs are unspecified and subject to change. Consequently, local variables implicitly assigned values by the compiler are still considered to be uninitialized.

A local variable is considered to be used anywhere its value is examined. This includes being passed as a USES or MODIFIES argument in a PROCEDURE call and being returned as a PRODUCES parameter.

Note that the definition of “use” for PRODUCES parameters can cause seemingly innocent programs to blow up with an “uninitialized variable” error if they are compiled with UCHECK in effect. For example, consider a BOOLEAN PROCEDURE with a PRODUCES parameter where the parameter has meaning only if the PROCEDURE's result is TRUE. If the PROCEDURE result is FALSE, then the PRODUCES argument has no meaning and should not be used by the caller. The implementer of the PROCEDURE may choose to initialize the PRODUCES parameter only in those cases where the PROCEDURE will return TRUE as its result; in all other cases, the PRODUCES argument would be uninitialized upon return to the PROCEDURE's caller. In these cases, if UCHECK were in effect, an “uninitialized PRODUCES parameter” error would occur just before the PROCEDURE returned, because of the parameter's implicit use at that point, even though the corresponding uninitialized argument may not actually be used by the caller. To avoid the error, the PRODUCES parameter should always be initialized, even if it is known that the PROCEDURE's caller will not actually use the value returned.

4.45. UNBOUND/NOUNBOUND

Temporary feature: subject to change

Default: NOUNBOUND

UNBOUND specifies that subsequently compiled MODULEs are nonbound-invocation MODULEs, i.e., always allocated as nonbound data sections by $invokeModule. Nonbound-invocation MODULEs are further described as temporary features in the Section 11.16 of the MAINSAIL Language Manual.

4.46. # s

The # character in compiler subcommand mode introduces a comment. It is especially useful in command files.
previous   next   top   contents   index   framed top   this page unframed

MAINSAIL Compiler User's Guide, Chapter 4