Go to the first, previous, next, last section, table of contents.

GPI files -- GNU Pascal Interfaces

This file documents the mechanism how information is transferred from the exporting Modules and Units to the Program, Module or Unit which imports (uses) the information.

The GPI mechanism is not (yet :-) as stable as it should be. If you encounter problems with your Modules or Units, please do the following:

The GPI mechanism

A GPI file contains a precompiled GNU Pascal Interface. "Precompiled" means in this context that the Interface already has been parsed (i.e the front-end has done its work), but that no assembler output has been produced yet.

The GPI file format is an implementation-dependent (but not too implementation-dependent ;-) file format for storing GNU Pascal Interfaces to be exported--Extended Pascal and PXSC module interfaces as well as interface parts of Borland Pascal Units compiled with GNU Pascal.

To see what information is stored in or loaded from a GPI file, run GPC with an additional command-line option --debug-gpi. Then, GPC will write a human-readable version of what is being stored/loaded to stderr.

While parsing an Interface, GPC stores the names of exported objects in tree lists--in gpc-parse.y, the bison (yacc) source of GPC's parser, search for handle_autoexport. At the end of the Interface, everything is stored in one or more GPI files. This is called in gpc-parse.y--search for create_gpi_files ().

Everything else is done in gpc-module.c. Here you can find the source of create_gpi_files () which documents the file format: First, a header of 33 bytes containing the string GNU Pascal Module/Unit Interface\n is stored, then the name of the primary source file of the module as a string, then the name of the exported interface as a tree node (see below), after that all exported names in the order as they were stored while parsing.

The names and the objects (i.e. constants, data types, variables and functions) they refer to are internally represented as so-called tree nodes as defined in the files tree.h and tree.def from the GCC source (i.e. the source of the GNU C compiler). The names are stored as IDENTIFIER_NODEs, their meanings as IDENTIFIER_GLOBAL_VALUEs of these nodes. The main problem when storing tree nodes is that they form a complicated tree in memory with a lot of circular references making it hard to decide which information must be stored and which mustn't.

The functions load_tree and store_tree are intended to load/store a tree node in a GPI file.

Each tree node has a TREE_CODE indicating what kind of information it contains. Each different tree node must be stored in a different way. See the source of load_tree and store_tree for details.

Most tree nodes contain pointers to other tree nodes; therefore load_tree and store_tree are recursive functions. The --debug-gpi debugging informations contains the recursion level in parantheses, e.g. loaded (2): means that the loaded information was requested by a pointer contained in a tree node requested by a pointer contained in a tree node representing an exported symbol.

Since this recursion can be circular (think of a record containing a pointer to a record of the same type), we must resolve references to tree nodes which already have been loaded. For this reason, and for saving disk space, I have introduced a gpi_contents list containing pointers to all nodes so far loaded from / stored in the GPI file under consideration. When storing a node which already is in the gpi_contents list, a (normally invalid) TREE_CODE of 255 `(0xFF)' followed by the (int) index of the node in the gpi_contents list is stored instead. Like this, the reference uses 1 byte plus the size of an int (normally 4) in the GPI file. In the debugging information, this method of storing/loading is indicated as via gpi_contents.

There are some special tree_nodes (e.g. integer_type_node or NULL_TREE) which are used very often. I have assigned (normally invalid) unique TREE_CODES for them, so they can be stored in a single byte.

That's it. Now you should be able to "read" GPI files using GPC's --debug-gpi option. If you encounter a case where the loaded information differs too much from the stored information, you have found a bug--congratulations! What "too much" means, depends on the object being stored in / loaded from the GPI file. Remind that the order things are loaded from a GPI file is the reversed order things are stored when considering different recursion levels, but the same order when considering ths same recursion level.


Go to the first, previous, next, last section, table of contents.