10. Intermodular analysis

  1. 10.1. Linking symbol table dump files
  2. 10.2. Linking C++ spec files
  3. 10.3. Template compilation

All the checks discussed in earlier chapters have been concerned with a single source file. However, tcc also contains a linking phase in which it is able to perform intermodular checks (i.e. checks between source files). In the linking phase, the files generated from each translation unit processed are combined into a single file containing information on all external objects within the application, and type consistency checks are applied to ensure that the definitions and declarations of each object are consistent and external objects and functions have at most one definition.

There are two types of file provided by tdfc2 for analysis; symbol table dump files and C++ spec files.

10.1. Linking symbol table dump files

The amount of information about an object stored in a dump file depends on the compilation mode used to produce that file. For example, if extra prototype checks are enabled (see section 3.3), the dump file contains any information inferred about a function from its traditional style definition or from applications of that function. For example, if one file contains:

extern void f () ;
void g ()
{
	f ( "hello" ) ;
}

and another contained:

void f ( n )
int n ;
{
	return ;
}

then the inferred prototype:

void f WEAK ( char * ) ;

from the call of f would be included in the first dump file, whereas the weak prototype deduced from the definition of f:

void f WEAK ( int ) ;

would be included in the second. When these two dump files are linked, the inconsistency is discovered and an error is reported.

10.2. Linking C++ spec files

The overall compilation scheme controlled by tcc, as it relates to the C++ producer, can be represented as follows:

tcpplus trans, as a.cc a.j a.o a.K b.cc b.j b.o b.K c.cc c.j c.o c.K x.j x.o x.K spec linker a.out
Figure 2. Compilation Scheme

Each C++ source file, a.cc say, is processed using tcpplus to give an output TDF capsule, a.j, which is passed to the installer phase of tcc. The capsule is linked with any target dependent token definition libraries, translated to assembler and assembled to give a binary object file, a.o. The various object files comprising the program are then linked with the system libraries to give a final executable, a.out.

A C++ spec file is a dump of the C++ producer's internal representation of a translation unit. Such files can be written to, and read from, disk to perform such operations as intermodule analysis.

In addition to this main compilation scheme, tcpplus can additionally be made to output a C++ spec file for each C++ source file, a.K say. These C++ spec files can be linked, using tcpplus in its spec linker mode, to give an additional TDF capsule, x.j say, and a combined C++ spec file, x.K. The main purpose of this C++ spec linking is to perform intermodule checks on the program, however in the course of this checking exported templates which are defined in one module and used in another are instantiated. This extra code is output to x.j, which is then installed and linked in the normal way.

Note that intermodule checks, and hence intermodule template instantiations, are only performed if the -im option is passed to tcc.

The TenDRA checker is similar to the compiler except that it disables TDF output and has intermodule analysis enabled by default.

The C++ spec linking routines have not yet been completely implemented, and so are disabled in the current version of the C++ producer.

Note that the format of a C++ spec file is specific to the C++ producer and may change between releases to reflect modifications in the internal type system. The C producer has a similar dump format, called a C spec file, however the two are incompatible. If intermodule analysis between C and C++ source files is required then the tdfc2dump symbol table dump format should be used.

10.3. Template compilation

The C++ producer makes the distinction between exported templates, which may be used in one module and defined in another, and non-exported templates, which must be defined in every module in which they are used. As in the ISO C++ standard, the export keyword is used to distinguish between the two cases. In the past, different compilers have had different template compilation models; either all templates were exported or no templates were exported. The latter is easily emulated - if the export keyword is not used then no templates will be exported. To emulate the former behaviour the directive:

#pragma TenDRA++ implicit export template on

can be used to treat all templates as if they had been declared using the export keyword.

The automatic instantiation of exported templates has not yet been implemented correctly. It is intended that such instantiations will be generated during intermodule analysis (where they conceptually belong). At present it is necessary to work round this using explicit instantiations.