6.4.1. Source Code Analysis for C, C++ and CUDA C++¶
6.4.1.1. Introduction¶
The information in this chapter is only relevant to the C/C++ and CUDA variants of the Axivion Suite .
For the C/C++ and CUDA analysis, the first step is to configure the original build system in a
way that instead of the original compiler, the Axivion C/C++ compiler cafeCC is
being called. For this to succeed, the Axivion compiler cafeCC has to behave as
closely as possible to the compiler you originally use. This configuration is called a
“compiler profile”.
The following tools may be used during this process:
- cafeCC (C and C++ compiler driver)
cafeCCis the front end tocafe,giraffeandirlink. When callingcafeCCwith option-c, C/C++ and CUDA C++ translation units are processed bycafeand Assembler files are processed bygiraffe. C/C++ and CUDA C++ files are preprocessed (with an internal preprocessor) and compiled like with an ordinary compiler but analysis data is gathered. If the system is to be linked,cafeCCcallsirlink. Generally, you should prefer callingcafeCCinstead ofgiraffe,cafe, andirlink.cafeCChas a command-line syntax similar togccandcl.exe, so if the to be analyzed project uses e. g.gcc, it is fairly simple to analyze with the Axivion Suite by just replacing calls togccwith calls tocafeCC.
- cafe (C and C++ Analyzer Front End)
cafeis the language front end for C, C++ and CUDA C++ that creates object files containing intermediate representation data (IR). We call the resulting files IR unit files. It accepts K&R C, ANSI-C 89/ISO-C 90, ISO-C 99 and ISO-C 11 in C mode, and ISO-C++ 98, ISO-C++ 11, ISO-C++ 14, ISO-C++ 17 and ISO-C++ 20 in C++ mode. In addition you can explicitly enable or disable GNU C and C++ and Microsoft C++ extensions if you need them via command-line switches. In CUDA mode,cafeaccepts CUDA C++ as described by the NVIDIA CUDA C++ Programming Guide up to version 13.0.
- giraffe (Generic IR Assembler Faking Front End)
giraffeis a front-end which reads in Assembler files an generates IR unit files with the Assembler content in an according IR container for linking. You cannot do in-depth analysis on the Assembler code automatically, but you get the code in the IR data so you can access it by means of scripting if you need to.
- irlink
irlinkis the linker for IR files. It performs global name resolution on IR unit files and generates a globally linked IR system file which describes the whole system.irlinkcan combine IR files for C/C++ and CUDA C++, but usually you do not need to worry about those things ascafeCCalready takes care of that.
- build_cbp
build_cbpcan be used to analyze Code::Blocks project files for C/C++ projects (.cbp) and issues the necessary calls tocafeCC.
- build_compile_commands
build_compile_commandscan be used to analyze a C/C++ project based on a previously generatedcompile_commands.jsonfile (e. g. withcmake -DCMAKE_EXPORT_COMPILE_COMMANDS=ONorbear) and issues the necessary calls tocafeCC.
- build_ewp
build_ewpcan be used to analyze IAR Systems Embedded Workbench project files for C/C++ projects (.ewp) and issues the necessary calls tocafeCC.
- build_gpj
build_gpjcan be used to analyze Green Hills Software MULTI project files for C/C++ projects (.gpj). It will use Green Hills’gpjmodifyto create aMakefileand then use amake.exeutility with the createdMakefileto issue the necessary calls tocafeCC.
- build_sln
build_slncan be used to analyze Microsoft Visual Studio solution files for C/C++ projects (.sln). It will use Microsoft’sMSBuildto issue the necessary calls tocafeCC.
- build_uvprojx
build_uvprojxcan be used to analyze Keil µVision project files for C/C++ projects (.uvprojx) and issues the necessary calls tocafeCC.
- build_vcxproj
build_vcxprojcan be used to analyze Microsoft Visual Studio project files for C/C++ projects (.vcxproj). It will use Microsoft’sMSBuildto issue the necessary calls tocafeCC.
- irWRAPPERS
The following tools exist:
irAR,irCC,irCP,irCXX,irLD,irLIBTOOL,irLN,irLTORANLIB,irMT,irMV,irNVCC,irOBJCOPY,irOBJDUMP,irRANLIB,irSIZE,irSTRIP. Those wrapper scripts can be used in-place of their native counterparts in order to compile native objects and Axivion IR at the same time.
- axivion_injector
axivion_injectorcan be used to prepend native compiler/linker calls to inject the Axivion compiler/linker. Depending on further parameters, the behavior can be selected as desired.
- srcCP
srcCPcan be used in case source files are copied from their version-controlled location to a temporary/build location and used during the compilation from there. In such case, the files cannot be looked up in the VCS by default because they are used from a different path. UsingsrcCPyou can patch the copied source files with a#linedirective (either “inplace” or when copying or patching an existing copy) or an#includedirective (only when copying or patching an existing copy). This way you can create a “back mapping” from the copied source files to the original source files that are under version control.
6.4.1.2. cafeCC¶
cafeCC is the front end to cafe, giraffe and irlink.
When calling cafeCC with option -c, C/C++ and CUDA C++ translation units are
processed by cafe and Assembler files are processed by giraffe. C/C++
and CUDA C++ files are preprocessed (with an internal preprocessor) and compiled like with an
ordinary compiler but analysis data is gathered. If the system is to be linked,
cafeCC calls irlink. Generally, you should prefer calling cafeCC
instead of giraffe, cafe, and irlink. cafeCC has a
command-line syntax similar to gcc and cl.exe, so if the to be analyzed
project uses e. g. gcc, it is fairly simple to analyze with the Axivion Suite
by just replacing calls to gcc with calls to cafeCC.
By using cafeCC, existing Makefiles can be reused easily for the source code
analysis in the context of the Axivion Suite. Most Makefiles use variables for
specifying the tools to be used during the make process. The variable used for the C
compiler is usually called CC, the one for the C++ compiler is usually called
CXX.
If your Makefiles use these variables, you can compile your system with the Axivion Suite as follows:
make clean
make CC=cafeCC CXX=cafeCC
Note
If you have compiled your system with a C or C++ compiler previously, you have to delete your object files and executables when choosing this approach.
cafeCC handles object libraries generated with ar correctly. Shared
objects (.so) are either correctly linked in (if they are already linked IR
files) or ignored (if they are real shared object files with executable code inside).
The object files that are being created by cafeCC (or rather its backends
cafe and giraffe) are in fact IR unit files. You cannot link them
using the linker of your compiler toolchain, but with the IR linker cafeCC
(or rather its backend irlink). A linked IR file is also called IR system
file.
Compiling your sources using cafeCC out of context of an Axivion CI will
capture the whole path of each translation unit starting at the root of your file
system. You will get a warning
No Basepath specified, all filenames will be absolute for each compilation
unit in that case.
If called from within an Axivion CI (axivion_ci),
all paths will get stripped at the so called basepath or project directory. This is
achieved by setting the environment variable CAFECC_BASEPATH to
/Project/directory.
cafeCC uses environment variable CAFECC_BASEPATH to strip all
absolute path names to relative ones. You can also use command-line switch
-B to set the basepath - which even overwrites a possibly set environment
variable CAFECC_BASEPATH. However:
Caution
Please try to avoid setting CAFECC_BASEPATH or -B and
let axivion_ci implicitly set the basepath, as it
does more harm than good if the CI sets it differently than your manually set
configuration.
Caution
Sometimes, most often on UNIX, the file extension .C (an upper-case C
character) is used as file extension for C++ files. On Windows®, .C cannot
be distinguished from .c anymore, and files ending with .C get
treated as C files and not C++ files. Either use a different file extension like
.cc, .cpp, .cxx or .c++ instead or specify the
command-line option -lang-c++ or -lang-c in case of
ambiguity when calling cafeCC.
Manual compiler profile configuration¶
cafeCC has to be configured accordigly to the compiler it is going to replace
in the analysis build, i.e. it must be configured like a gcc if it needs to
replace a gcc, it must be configured like Microsoft’s cl.exe if it
needs to replace cl.exe, it must be configured like clang, if it needs
to replace clang, and so on.
This configuration is called a “compiler profile” and typically consists of the
following settings that can all be configured from within axivion_config in
the respective compiler toolchain rule.
Note
The compiler profile is intended to match the original compiler’s default
settings and behavior for one specific target configuration, but not include
project-specific settings like non-default language version, includes or even
defines. E.g. if your project is compiled in C++14 mode, but the default C++ mode of
your compiler is C++17, then in the compiler profile it should be C++17 and not
C++14, as the language selection to C++14 is not the compiler’s default, but is done
during compilation on the command line (with a switch like -std=c++14 or
/std:c++14 etc.).
The most important configuration options for each compiler toolchain rule are:
Language Version (
language_c.language_versionandlanguage_cxx.language_version):This sets the default language version for C and C++ respectively (e.g.
C90,C99, etc.).Language Dialect (
language_c.emulated_compilerandlanguage_cxx.emulated_compiler) and specific version (language_c.emulated_compiler_versionandlanguage_cxx.emulated_compiler_version):If required, you can specify a dialect (like
GNU,Microsoft, orClang) together with a specific version (like90300,110100, or1929respectively).For Visual Studio, the official name, the Visual Studio version and the compiler version (
_MSC_VERmacro) are different and some important values can be seen in the following table:Official Visual Studio Name
Visual Studio Version
_MSC_VERVisual Studio
4.2
1020
Visual Studio 97
5.0
1100
Visual Studio 6.0
6.0
1200
Visual Studio .NET (2002)
7.0
1300
Visual Studio .NET 2003
7.1
1310
Visual Studio 2005
8.0
1400
Visual Studio 2008
9.0
1500
Visual Studio 2010
10.0
1600
Visual Studio 2012
11.0
1700
Visual Studio 2013
12.0
1800
Visual Studio 2015
14.0
1900
Visual Studio 2015 Update 3
14.0
1903
Visual Studio 2017
15.0
1910
Visual Studio 2017 Update 9
15.9
1916
Visual Studio 2019
16.0
1920
Visual Studio 2019 Update 11
16.11
1929
Visual Studio 2022
17.0
1930
Visual Studio 2022 Update 10
17.10
1940
Visual Studio 2026
18.0
1950
The full table with all update versions can be found in Microsoft’s documentation at Microsoft C++ (MSVC) compiler versioning<https://learn.microsoft.com/en-us/cpp/overview/compiler-versions>.
Predefined Macros (
language_c.preprocessing.predefined_macrosandlanguage_cxx.preprocessing.predefined_macros):Compiler predefined macros that are required for correct preprocessing can be configured here.
cafeCCadditionally sets the macros__AXIVION__and__AXIVION_VERSION__that can be used for adjusting the source code under analysis when it does not adhere to the supported C/C++ dialects or if you want to remove certain code from analysis.System Header Include Paths (
language_c.preprocessing.sys_include_pathandlanguage_cxx.preprocessing.sys_include_path):You can configure the include paths where
cafeCClooks for standard headers in addition to all--sys_includeswitches that are given at compilation time on the command-line.If no explicit directories
language_c.preprocessing.sys_include_pathandlanguage_cxx.preprocessing.sys_include_pathare set, the include paths can also be looked up via environment variables. This can be configured vialanguage_c.preprocessing.sys_include_envvarandlanguage_cxx.preprocessing.sys_include_envvarrespectively for system includes andlanguage_c.preprocessing.user_include_envvarandlanguage_cxx.preprocessing.user_include_envvarrespectively for user includes.Compiler toolchain rule
GnuToolchainandClangToolchainhave the environment variablesC_INCLUDE_PATHas default for C system include path,CPLUS_INCLUDE_PATHas default for C++ system include path, andCPATHas default for user include path.Compiler toolchain rule
MicrosoftToolchainhas the environment variableINCLUDEas default for both, C and C++ system include path and it also guesses the Microsoft Visual Studio version from it.Type System (
types):You can specify the sizes of basic types and certain type aliases here.
The size of a
charis expressed in bytes, all other sizes are expressed in multiples of achar. For enums, you can configuretypes.short_enumsto pack them, and you can configure the preferred representation type (viatypes.preferred_enum_base_type) to one of the standard integer types (this type will be used if the enumerator values fit, except when the code specifies a base type explicitly).The typedefs
wchar_t,wint_t,char16_t,char32_t,size_t, andptrdiff_thave special relevance to the compiler (e. g. in the type of wide string literals, or as the result type for thesizeofoperator). These types should be configured to the same basic integer types as used in the system headers. In C++ mode, these options also control the size and alignment for the built-in C++ typeswchar_t,char16_tandchar32_t.Preincludes (
preincludes):You can configure multiple preinclude files that are included before actual parsing of the source file even starts.
Those preinclude files can be used e. g. to redefine non-ANSI keywords or to add diagnostic suppressing pragmas.
Command-Line Switch Mapping (
switches.mapping):You can configure behavior of command-line switches by adding the switch names and their desired behavior here.
Switches that are not explicitly configured will emit a warning
Argument '-unknown_switch' ignoredfor each compilation unit.The following table lists a selection of options common to all compiler toolchain rules (including some
cafeCC-specific options):Option
Meaning
-cCompile, do not link.
-I <directory>Add include directory (only one directory can be specified per
-Ioption, use multiple-Iswitches to specify multiple include directories).-D <macro>[=value]Define a preprocessor macro (to a specific value).
-D <macro>sets the value of <macro> to be 1,-D <macro>=sets the value to nothing, but <macro> is defined, and-D <macro>=valuesets <macro> to be of the specified value.-U <macro>Undefine a preprocessor macro.
-l <library>Link against library.
-L <directory>Add directory to the library search path.
-B <path>Set source basepath to be removed from the source location information. The given path is removed from all source paths within the generated IR files.
-absolute_filenamesUse absolute filenames in diagnostics.
-no_absolute_filenamesUse relative filenames in diagnostics.
-with_ir_suffixAppend
.irto all object and library files.-continueDo not abort on errors but continue with the next file.
-touch_on_errorTouch the target file when an error occurs and otherwise no file would be generated.
-keep_preprocessedKeep or generate the preprocessed code (file extension
.ifor C files and.iifor C++ files).-j[n]Use <n> child processes for parallel compilation. Use the Default Parallelism logic if <n> is omitted.
-aarg <param>Pass on <param> to the IR assembler
giraffe.-carg <param>Pass on <param> to the IR compiler
cafe.-larg <param>Pass on <param> to the IR linker
irlink.-echoShow execution of child processes.
-log <file>Log calls to child processes to file.
The following table lists a selection of options specific to compiler toolchain rule
GNUToolchain:Option
Meaning
-o <file>Write output to <file>.
-include <file>Preinclude <file> before compiling source file.
-imacros <file>Preinclude only macros from <file> before compiling.
-isystem <directory>Search for system header in directory after all
-Ibut before the default system include directories.-idirafter <directory>Search for system header in directory after all
-Iand after the default system include directories.-x <lang>Specify language of the source files (c, c++, assembler). This setting overrides the extension of the file.
-sharedLink as library, i. e. keep unreferenced units (see
--sharedofirlink).-nostdincDo not use standard C include paths.
-nostdinc++Do not use standard C++ include paths.
-WallDisplay lots of warnings (default).
-Wextra,-WDisplay even more remarks.
-wSuppress warnings and remarks.
-HTrace includes (useful for debugging erroneously used include files).
The following table lists a selection of options specific to compiler toolchain rule
MicrosoftToolchain:Option
Meaning
/Fo <file>Write output to <file>.
/OUT:<file>Write output to <file>.
/LIBPATH:<directory>Add directory to the library search path.
/FI <file>Preinclude <file> before compiling source file.
/TCSpecify language of the source files as C. This setting overrides the extension of the file.
/TPSpecify language of the source files as C++. This setting overrides the extension of the file.
@<file>Read further options from <file>.
You can set default switches that are always passed to the tool
cafeby adding them in the rule optionslanguage_c.default_switchesandlanguage_cxx.default_switchesrespectively.
Automatic compiler profile configuration¶
For certain compilers we supply automatic configuration tools that generate a matching compiler profile for a specific compiler (in a specific mode of operation), namely:
Clang-based compilers (
clangsetup), includes e. g. Keil ARMClang, etc.GCC-based compilers (
gccsetup), includes e. g. Microchip XC16/XC32, Texas Instruments GCC compilers, Hightec GCC, QNX GCC, etc.Green Hills Software compilers (
ghssetup)IAR Systems compilers (
iarsetup)Texas Systems CGT compilers (
ticgtsetup)
The configuration tools can be called either without any argument in which case compiler profile configuration will enter interactive mode and you’ll have to manually specify C compiler (including flags), C++ compiler (including flags) and output file or folder of the compiler profile.
Alternatively you can also invoke the configuration tools directly with all the required information supplied on the command-line for non-interactive usage, e. g.:
gccsetup --cc "arm-none-eabi-gcc -mcpu=cortex-m4" --cxx "arm-none-eabi-gcc -mcpu=cortex-m4" --config axivion
Note
The compiler profile is intended to match the original compiler’s default
settings and behavior for one specific target configuration, but not include
project-specific settings like non-default language version, includes or even
defines. E.g. if your project is compiled in C++14 mode, but the default C++ mode of
your compiler is C++17, then in the compiler profile it should be C++17 and not
C++14, as the language selection to C++14 is not the compiler’s default, but is done
during compilation on the command line (with a switch like -std=c++14 or
/std:c++14, etc.). Therefore you should not supply any -std=c++14
or /std:c++14 etc. switches to the setup tool calls. However, switches that
select a specific target architecture (e.g. -mcpu=cortex-a3 or
--fpu=softvfp or --thumb, etc.) should be specified in the setup
tool.
Compiling IR and executable simultaneously¶
Sometimes you may want to compile with your native compiler at the same time as analyzing with the Axivion Suite and building the IR files. This can be necessary when you build executables during your build process which are executed in order to bootstrap something.
We supply scripts irCC, irCXX, irNVCC, irAR,
irCP, irMV, irLN, and irOBJCOPY which help in doing so
(refer to section irWRAPPERS for more details).
Normally, when just using cafeCC, the output are IR files in those places
where there are object files when using your native compiler. However, when using
irCC and irCXX, those objects files are generated with your native
compiler in their usual places and the IR files are generated next to them, but with
the suffix .ir appended. When you create archives with ar during your
build process, you also have to use irAR in order to create two archives, one
with object code and one with IR files.
In order to pass special options to cafeCC, you can specify them in the environment
variable CAFECC_OPTIONS. If you want to specify options only in case of C
files, use the variable CAFECC_CC_OPTIONS and for options that are only
passed for C++ files, use CAFECC_CXX_OPTIONS. For CUDA compilation with
irNVCC there also exists CAFECC_NVCC_OPTIONS.
In order to build and analyze your project simultaneously with setting the basepath for
the analyses to the root of your project and having some C++ files with unusual file
extensions in your project and making use of ar archives, you would use
something like the following call to start compilation:
CAFECC_BASEPATH=$(pwd) CAFECC_OPTIONS=-echo CAFECC_CXX_OPTIONS=-std=c++17 CC=irCC CXX=irCXX AR=irAR make
Using more than one compiler profile in one project¶
If you are working with just one compiler (e. g. one GCC) at a time, the setup as outlined above is sufficient. If however you need to use several different compilers in the same analysis build (e. g. different GCC cross-compilers), then you have to create a setup which is a bit more sophisticated. You need to prepare configuration files for each of the different compilers you use. At present, this process is not automated but you will have to do it manually.
First of all, you have to create compiler profiles for all relevant compilers. Then you
can use small wrapper scripts that explicitly select a specific compiler profile and
use them in your build process instead of cafeCC directly.
Example for compiler A:
$ cat cafeCC-A
#!/bin/sh
export BAUHAUS_CONFIG=/path/to/config/compiler_A.json:$BAUHAUS_CONFIG
cafeCC "$@"
Example for compiler B:
$ cat cafeCC-B
#!/bin/sh
export BAUHAUS_CONFIG=/path/to/config/compiler_B.json:$BAUHAUS_CONFIG
cafeCC "$@"
Then you can use the scripts cafeCC-A and cafeCC-B respectively in your
build configuration.
IR Compression¶
By default, every IR (both object files and the linked IR) is compressed internally.
This can be configured using the BAUHAUS_IR_COMPRESSION environment
variable.
Option |
Meaning |
|---|---|
|
Do not use compression when saving IRs. |
|
gzip compression level 1 (available levels: 1 to 9) |
|
zstd compression level 1 (available levels: -4 to 19) |
Compression helps reduce the space taken by object files on disk. However, it can also slow down compilation and especially linking.
6.4.1.3. cafe¶
cafe is the language front end for C and C++ that creates object files
containing intermediate representation data (IR). We call the resulting files IR unit
files. It accepts K&R C, ANSI-C 89/ISO-C 90, ISO-C 99 and ISO-C 11 in C mode, and
ISO-C++ 98, ISO-C++ 11, ISO-C++ 14, ISO-C++ 17 and ISO-C++ 20 in C++ mode. In addition you can explicitly enable
or disable GNU C and C++ and Microsoft C++ extensions if you need them via
command-line switches.
Command-Line Switches¶
Caution
You should not call cafe directly from the command-line as its usage is quite
complex; always use cafeCC instead.
However cafeCC understands additional switches starting with double-hyphen that
are passed directly to cafe.
Option |
Meaning |
|---|---|
|
Treat @ as letter if directly followed by another letter. |
|
Treat @ as operator symbol (unless directly followed by a letter and switch |
|
Enable IAR-style float literals 0.NaN and 0.Infinity. |
|
Enable binary literals via prefix 0b. |
|
Display size and alignment of basic types used in the current configuration and exit. |
|
Format the primary position of messages as “file:line:col” instead of “file”, line L (col. C). |
|
Format the primary position of messages as “file”, line L (col. C). |
|
Activate special keywords that can be used via macro definitions to skip certain tokens (see Section Ignore Tokens). |
|
Treat |
|
Treat symbols as dllimport if they are not marked dllexport nor dllimport (may be useful to avoid duplicates after linking if the source code omits the declspec for legacy reasons). |
|
Writes out file |
|
Set exit code to nonzero if a syntax/semantic error was reported. |
|
Do not record #line directives, use physical positions only. |
|
Specify root directory for relative filenames in #line directives. Supported values for <param> are:
|
|
Reduce memory usage for large aggregates. |
|
Use minimalistic representation for asm statements. |
|
Treat asm functions like static (unit-local) functions. |
|
Do not ignore the rest of the line after a semicolon inside braces in an __asm block |
|
Do not ignore the rest of the line after a semicolon in a Microsoft-style non-block __asm statement |
|
Try to accept different assembler flavors; treats __asm and asm the same and allows GNU extensions in other language modes. |
|
Enable compilation of CUDA C++ code. |
|
Do not keep preprocessor #if information in IR. |
|
Use strict MS emulation: treat array new and delete as synonym for non-array counterparts |
|
Use strict MS emulation: drop exception specifications |
|
Enables support for C99 flexible array members |
|
Enables support for the C11 _Generic keyword |
|
Enables support for the C11 _Atomic keyword |
|
Support GNU-style attributes in non-GNU modes |
|
Create smaller IR file (removing those symbols and declarations in system headers which are not referenced from primary files or user headers) |
|
Treat member functions of template (instance) classes like normal functions for MisraC++-14.8.2 |
|
Do not store compiler messages in the resulting IR |
|
When an #include target file cannot be opened, continue with a normal instead of catastrophic error |
|
Enables support for the clang feature tests macros: |
The front end is invoked by calling cafeCC and not by calling cafe
directly. It is invoked by a command of the form
cafeCC [options] <inputfile>...
to compile (and link) the single input file inputfile. If - (hyphen) is
specified for inputfile, the front end reads from stdin [9]. No particular
file name suffix is required on input files, however when cafeCC cannot guess
the language (this is especially the case if you read from stdin) you have to
specify the language with the option -lang-c or -lang-c++.
Command-line options may be specified using keyword options (e. g.
--output) and not using single character option codes (e. g.
-o) in general as cafeCC passes double-hyphen options directly to
cafe whereas single-hyphen options are interpreted by cafeCC. A keyword
specification consists of two hyphens followed by the option keyword (e. g.
--strict). Keyword options may be abbreviated by specifying as many of the
leading characters of the option name as are needed to uniquely identify an option name
(for example, the --wchar_t_keyword option may be abbreviated as
--wc). If an option requires an argument, the keyword must be immediately
followed by =option. There may not be any white space on either side of the equal
sign.
When one of the preprocessing-only modes is specified (see below), the
--output option can be used to specify the preprocessing output file. If
--output is not specified, preprocessing output is written to stdout.
Preprocessing output has trigraphs and line splices processed (and thus they do not
appear in their original form).
Note
The following sections are taken from the external documentation of the underlying EDG C/C++ parsing front end and is reprinted with permission. Copyright belongs to Edison Design Group, Inc.
Language Dialect Options¶
The following options select among various C and C++ dialects.
--anachronisms--no_anachronisms |
Enable or disable anachronisms in C++ mode. This option is valid only in C++ mode. |
--c-m |
Enable compilation of C rather than C++. |
|
Enable the compilation of the C89 version of C. |
--c99--no_c99 |
Enable or disable compilation of the C99 version of C. In either case, C rather than C++ is compiled. |
|
Enable language features added in the C11 standard. This option cannot be combined with options enabling or requiring a C++ mode. |
--c18--c17 |
Enable support for C18 (which is only a minor “bug fix” change from C11). This option cannot be combined with options enabling or requiring a C++ mode. |
|
Enable language features added in drafts of the anticipated C23 standard. This option cannot be combined with options enabling or requiring a C++ mode. |
--old_c-K |
Enable K&R/pcc mode, which approximates the behavior of the standard
UNIX |
--c++-p |
Enable compilation of C++. This is the default. |
|
Enable compilation of C++ as specified by the ISO/IEC 14882:2003
standard by explicitly disabling all C++11 features, regardless of their
configured default values (but individual C++11 features can be enabled
on the command line). This option implicitly enables C++ mode and can be
combined with the options enabling strict ANSI/ISO conformance, as well
as other emulation modes (e.g., |
--c++11--no_c++11--c++0x--no_c++0x |
Enable or disable extensions added in the C++11 standard. This option is only valid in C++ mode and can be combined with the options enabling strict ANSI/ISO conformance. |
|
Enable language features added in the C++14 standard. This option cannot be combined with options enabling or requiring a C mode. |
|
Enable language features added in the C++17 standard. This option cannot be combined with options enabling or requiring a C mode. |
|
Enable language features added in the C++20 standard. This option cannot be combined with options enabling or requiring a C mode. |
|
Enable language features added in the C++23 standard. This option cannot be combined with options enabling or requiring a C mode. |
|
Enable language features added in drafts of the anticipated C++26 standard. This option cannot be combined with options enabling or requiring a C mode. |
--cfront_2.1-b |
Enable compilation of C++ with compatibility with cfront version 2.1. This causes the compiler to accept language constructs that, while not part of the C++ language definition, are accepted by the AT&T C++ Language System (cfront) release 2.1. This option also enables acceptance of anachronisms. |
|
Enable compilation of C++ with compatibility with cfront version 3.0. This causes the compiler to accept language constructs that, while not part of the C++ language definition, are accepted by the AT&T C++ Language System (cfront) release 3.0. This option also enables acceptance of anachronisms. |
--c++cli--no_c++cli--cppcli--no_cppcli--clr |
Enable or disable compilation of C++/CLI source. This option
implies Microsoft C++ mode; it cannot be combined with options that are
contrary to such a mode (e.g., forcing strict mode) or with the option
|
--c++cx--no_c++cx--cppcx--no_cppcx |
Enable or disable compilation of C++/CX source. This option
implies Microsoft C++ mode; it cannot be combined with options that are
contrary to such a mode (e.g., forcing strict mode) or with the option
|
--clang--no_clang |
Enable or disable clang C or C++ language compatibility features. This option also enables the GNU C or C++ language compatibility features. |
|
The version of the clang compiler that should be emulated. Version x.y.z
of the clang compiler is encoded as x*10000+y*100+z (e.g., version 3.4.1
is emulated with the option |
--embedded_c--no_embedded_c |
Enable or disable support for all Embedded C language extensions (fixed-point types, named address space qualifiers, and named-register storage class specifiers). These options are not available with C++ modes. |
|
Enable the diagnosis of noncompliance with the “Embedded
C++” subset (from which templates, exceptions, namespaces, new-style
casts, RTTI, multiple inheritance, virtual base classes, and |
--g++--no_g++ |
Enable or disable GNU C++ language compatibility features. This option also specifies that the source language being compiled is C++. |
--gcc--no_gcc |
Enable or disable GNU C language compatibility features. This option also specifies that the source language being compiled is C. |
|
The version of the GNU compiler that should be emulated in any of the
GNU (C or C++) modes. Version x.y.z of the GNU compiler is encoded as
x*10000+y*100+z (e.g., version 3.4.1 is emulated with the option
|
--microsoft--microsoft_16--no_microsoft |
Enable or disable Microsoft emulation mode. |
|
The version of the Microsoft compiler that should be emulated in
Microsoft mode. This enables or disables particular Microsoft mode
features when the acceptance of those features varies between versions
of the Microsoft compiler. The value specified is the value of the
predefined macro |
|
The “build number” of the Microsoft compiler that should be emulated in
Microsoft mode (this option also enables Microsoft mode). This value is
used to set the value of the predeclared macro |
--microsoft_bugs--no_microsoft_bugs |
Enable or disable recognition of certain Microsoft bugs. These options also enable Microsoft mode. Microsoft bugs mode is automatically enabled when Microsoft mode is used. |
|
Emulate the Microsoft Visual Studio |
|
Emulate the Microsoft Visual Studio |
|
Emulate the Microsoft Visual Studio |
|
Emulate the Microsoft Visual Studio |
|
Emulate the Microsoft Visual Studio |
|
Emulate the Microsoft Visual Studio |
|
Emulate the Microsoft Visual Studio |
|
Emulate the Microsoft Visual Studio |
|
Emulate the Microsoft Visual Studio |
|
Emulate the Microsoft Visual Studio |
--ms_compatibility--no_ms_compatibility |
Enable or disable certain Microsoft compatibility
options (as defined by the clang |
--ms_std_preprocessor--no_ms_std_preprocessor |
Enable or disable a mode in which the behavior of the preprocessor in Microsoft emulation mode conforms with the C and C++ Standards; when disabled, the preprocessor emulates the behavior of the traditional Microsoft preprocessor. |
--ms_stdc--no_ms_stdc |
Emulate the |
--ms_cplusplus_std_value--no_ms_cplusplus_std_value |
Emulate the |
--ms_extensions--no_ms_extensions |
Enable or disable certain Microsoft extensions (as
defined by the clang |
--ms_permissive--no_ms_permissive |
Enable or disable “permissive” mode during Microsoft
emulation. These command-line options control emulation of the Visual
Studio |
--nonstd_gnu_keywords--no_nonstd_gnu_keywords |
In GNU modes, |
--no_strict_gnu--strict_gnu |
For every version of the C and C++ ISO standards, the GNU and Clang compilers
support both the language as defined by ISO (with |
--strict_warnings or -a--strict or -A |
Enable strict ANSI/ISO mode, which provides diagnostic
messages when nonstandard features are used, and disables features that
conflict with ANSI/ISO C or C++. This is compatible with both C and C++
mode. It is not compatible with pcc mode. ANSI/ISO violations can be
issued as either warnings or errors depending on which command line
option is used. The |
|
If a selected dialect weakens the type checking performed in a template, adding this option makes it stricter again (although not always as strict as what is done in strict ANSI/ISO mode). |
--sun--no_sun |
Enable or disable Sun CC (version 5.x) language compatibility features. This option can only be used in C++ mode, and cannot be combined with options to enable strict ANSI mode, or compatibility with cfront, Microsoft, or GNU. |
--svr4--no_svr4 |
Enable or disable recognition of SVR4 C compatibility features. This option also specifies that the source language being compiled is ANSI C. |
--upc--no_upc |
Enable or disable UPC (Unified Parallel C) extensions. |
|
Specify a fixed number of UPC threads (this is the
value of the |
--upc_strict--upc_relaxed |
Specify the default UPC access method for objects of shared types. |
Input/output Options¶
The following options control the kind of input read or output produced or the location of such input or output.
|
Source input files that do not begin with a byte order mark indicating
the kind of Unicode encoding are assumed to use the Unicode encoding
indicated by kind. Possible values of kind are |
|
Do preprocessing only. Instead of the normal preprocessing output,
generate on the preprocessing output file a list of dependency lines
suitable for input to the UNIX |
|
Redirect the output that would normally go to the
error output file (i.e., diagnostic messages) to the file efile. This
option is useful on systems where output redirection of files is not
well supported. If used, this option should probably be specified first
in the command line, since otherwise any command-line errors for options
preceding the |
--list <lfile>-L<lfile> |
Generate raw listing information in the file lfile. This information is likely to be used to generate a formatted listing. The raw listing file contains raw source lines, information on transitions into and out of include files, and diagnostics generated by the front end. Each line of the listing file begins with a key character that identifies the type of line, as follows:
where S is |
|
Do preprocessing only. Instead of the normal preprocessing output, generate on the preprocessing output file a list of all the macros in effect after processing the source file, including predefined and command-line macros along with their definitions. |
--no_line_commands-P |
Do preprocessing only. Write preprocessed text to the preprocessing output file, with comments removed and without line control information. |
|
When generating source output (e.g., with the
C-generating back end), put out |
--output <ofile>-o <ofile> |
Specify the output file of the compilation, i.e., the preprocessing or intermediate language output file. |
--xref <xfile>-X<xfile> |
Generate cross-reference information in the file xfile. For each reference to an identifier in the source program, a line of the form symbol-id name ref-code file-name line-number column-number
is written, where ref-code is |
Preprocessor Options¶
The following options control the behavior of the preprocessor.
--comments-C |
Keep comments in the preprocessed output. This should be specified
after either |
--define_macro <name> [ ( <parm-list>) ] [ = <def> ]-D <name> [ ( <parm-list>) ] [ = <def> ] |
Define macro name as def. If “= def ” is omitted, define name as 1. Function-style macros can be defined by appending a macro parameter list to name. |
|
Add dir to the list of directories searched for #embeds. The process by which files named in #embed directives are found is similar to that used for #include. See section finding-include-files. |
|
Specify the directory in which the files to be
included by |
|
Specifies the list of suffixes to be used when searching for an include file whose name was specified without a suffix. The argument is a colon-separated list of suffixes (e.g., “h:hpp::”). If a null suffix is to be allowed, it must be included in the suffix list. |
--include_directory <dir>--sys_include <dir>-I<dir> |
Add <dir> to the list of directories searched for |
|
Add <dir> to the list of directories searched for module files when processing an
import directive. The current working directory is automatically added to the
start of this list. If the |
|
Add <module_file> to the header unit map, corresponding to <header_path>. When importing a header unit, if the resolved path to the header matches <header_path>, then <module_file> is used as the match. See section finding-module-files. |
--ms_header_unit_angle <header_path>=<module_file>--ms_header_unit_quote <header_path>=<module_file> |
Add <module_file>, corresponding to <header_path>, to a header unit map selected by
the form in which header_path is written, |
|
If <module_name> is omitted, <file> will be examined to determine if the module it represents matches the module named in the import directive. Otherwise, an import of <module_name> will resolve to <file> without examining its contents. See section finding-module-files. |
--ms_translate_include--no_ms_translate_include |
Enable or disable the automatic translation of |
|
Forces pcc style preprocessing when compiling in ANSI C or C++ mode. This may be used when compiling an ANSI C or C++ program on a system in which the system header files require pcc style preprocessing. |
--preinclude_macros <filename>--preinclude <filename>--sys_preinclude <filename> |
Include the source code of the indicated file at
the beginning of the compilation. This can be used to establish standard
macro definitions, etc. The file name is searched for in the directories
on the include search list. When the |
-E |
Do preprocessing only. Write preprocessed text to the preprocessing output file, with comments removed and with line control information. |
|
May be used in conjunction with the options that normally cause the front
end to do preprocessing only (e.g., |
--stdc_zero_in_system_headers--no_stdc_zero_in_system_headers |
Enable or disable special processing of the |
--trace_includes-H |
Output a list of the names of files |
--undefine_macro <name>-U<name> |
Remove any initial definition of the macro name.
|
--check_concatenations--no_check_concatenations |
Specifies whether or not the front end will issue a diagnostic if a
concatenation operator |
|
Used in connection with options that generate preprocessing output, suppresses the extra spaces the front end inserts in the text of macro expansions to ensure that tokens that should not be combined remain separate tokens. This can be used to prevent the insertion of extraneous spaces when the front end is used as a preprocessor for text that is not C or C++. |
Diagnostic Options¶
The following options control when or how diagnostics are emitted.
--add_match_nodes--no_add_match_nodes |
Enable or disable diagnostic notes that provide further details for a failure to match candidates in an overload set. This feature is enabled by default. |
--brief_diagnostics--no_brief_diagnostics |
Enable or disable a mode in which a shorter form of the diagnostic output is used. When enabled, the original source line is not displayed and the error message text is not wrapped when too long to fit on a single line. |
--colors--no_colors |
Enable or disable colorization of diagnostic messages. Colorized diagnostics are
disabled by default. They will also be disabled when
not writing to a terminal, and are also disabled when the |
|
Set the context limit to number. The context limit is the maximum number of template instantiation context entries to be displayed as part of a diagnostic message. The default is 10. If the number of context entries exceeds the limit, the first and last N context entries are displayed, where N is half of the context limit. A value of zero is used to indicate that there is no limit. |
--diag_suppress <tag, tag, ...>--diag_remark <tag, tag, ...>--diag_warning <tag, tag, ...>--diag_error <tag, tag, ...> |
Override the normal error severity of the specified diagnostic messages. The message(s) may be specified using a mnemonic error tag or using an error number. The error tag names and error numbers are listed in the Error Messages appendix. |
|
Causes the specified diagnostic to be issued only once as a warning or remark. The message(s) may be specified using a mnemonic error tag or using an error number. The error tag names and error numbers are listed in the Error Messages appendix. |
--display_error_number--no_display_error_number |
Enable or disable the display of an error message number in any diagnostic messages that are generated. The option may be used to determine the error number to be used when overriding the severity of a diagnostic message. |
--error_limit <number>-e <number> |
Set the error limit to number. The front end will abandon compilation after this number of errors (remarks and warnings are not counted toward the limit). By default, the limit is 100. |
--for_init_diff_warning--no_for_init_diff_warning |
Enable or disable a warning that is issued when programs compiled under the new for-init scoping rules would have had different behavior under the old rules. The diagnostic is only put out when the new rules are used. This option is valid only in C++ mode. |
--lossy_conversion_warning--no_lossy_conversion_warning |
Enable or disable a warning that is issued when conversion of an arithmetic value to a different type might result in lost data because the target type cannot represent all the values of the source type. |
--macro_positions_in_diagnostics--no_macro_positions_in_diagnostics |
Enable or disable display of extra information for diagnostics that refer to text in macro expansions. The additional information includes the original source line from which the text identified by the message was copied into the macro expansion (i.e., a macro definition or an argument in the top-level macro invocation), as well as the chain of macro invocations that led to the expanded text designated by the diagnostic. |
--promote_warnings-W |
Issue all warnings as if they were discretionary errors. |
--remarks-r |
Issue remarks, which are diagnostic messages even milder than warnings. |
|
Warn about the use of certain GNU extensions outside system header files. Only valid in GNU C or C++ mode. |
--template_typedefs_in_diagnostics--no_template_typedefs_in_diagnostics |
Enable or disable the replacement of typedefs declared in template classes with their underlying type. Diagnostic messages are often more useful when such typedefs are replaced. |
--timing-# |
Generate compilation timing information. This option causes the compiler to display the amount of CPU time and elapsed time used by each phase of the compilation and a total for the entire compilation. |
--no_use_before_set_warnings-j |
Suppress warnings on local automatic variables that are used before their values are set. The front end’s algorithm for detecting such uses is conservative and is likely to miss some cases that an optimizer with sophisticated flow analysis could detect; thus, an implementation might choose to suppress the warnings from the front end when optimization has been requested but to permit them when the optimizer is not being run. |
--no_warnings-w |
Suppress warnings. Errors are still issued. |
--wrap_diagnostics--no_wrap_diagnostics |
Enable or disable a mode in which the error message text is not wrapped when too long to fit on a single line. |
Individual Language Features¶
The following options enable or disable specific language syntax. (Options that affect the meaning of existing constructs are listed in section R-2.5.1.6.)
--alternative_tokens--no_alternative_tokens |
Enable or disable recognition of alternative tokens. This controls
recognition of the digraph tokens in C and C++, and controls recognition
of the operator keywords (e.g., |
--array_new_and_delete--no_array_new_and_delete |
Enable or disable support for array new and delete. This support is enabled by default. This option is valid only in C++ mode. |
--auto_storage--no_auto_storage |
Enable or disable the traditional meaning of |
--auto_type--no_auto_type |
Enable or disable auto as a type specifier where the
actual type is deduced from an initializer (only valid in C++ mode).
This is a C++11 feature. If enabled, the traditional meaning of auto as
a storage class specifier is disabled (which matches C++11), unless the
option |
--bool--no_bool |
Enable or disable recognition of |
--c23_typeof--no_c23_typeof |
Enable or disable support for the C23 |
--c++11_sfinae--no_c++11_sfinae |
Enable or disable template deduction in the style
dictated by the C++11 standard, i.e., where general expressions are
allowed in deduction contexts and they undergo the full usual semantic
checking. This type of deduction is necessary to get the full power of
the |
--c++11_sfinae_ignore_access--no_c++11_sfinae_ignore_access |
When new-style SFINAE is enabled, these options control whether or not
access errors cause deduction failures. The positive option indicates
that access checking should not be done during template deduction, and
therefore that access errors cannot cause a deduction failure; this was
the status quo ante when the new-style SFINAE rules were proposed. The
|
--char8_t--no_char8_t |
Enable or disable support for the |
--compound_literals--no_compound_literals |
Enable or disable support for “compound literals” (a C99 feature). |
--concepts--no_concepts |
Enable or disable support for concepts (a C++20 feature). |
--delegating_constructors--no_delegating_constructors |
Enable or disable delegating constructors (a C++11 feature). |
--deprecated_string_conv--no_deprecated_string_conv |
Enable or disable the deprecated conversion from a string literal to
|
--designators--no_designators |
Enable or disable support for designators (a C99 feature). |
--digit_separators--no_digit_separators |
Enable or disable support for digit separators (a
C++14 feature). When this feature is enabled, an apostrophe can appear
between the digits of a numeric literal and is ignored, e.g.,
|
--extended_designators--no_extended_designators |
Enable or disable support for “extended designators,” an extension accepted only in C mode to emulate the behavior of certain other C compilers when it comes to designators in aggregate initializers. |
--dollar-$ |
Accept dollar signs in identifiers. The default value of this option is specified in a configuration file. |
--exceptions--no_exceptions-x |
Enable or disable support for exception handling. |
--exc_spec_in_func_type--no_exc_spec_in_func_type |
Enable or disable exceptions being part of a function type (enabled by default in C++17 modes and disabled by default otherwise). |
--explicit--no_explicit |
Enable or disable support for the |
--export--no_export |
Enable or disable recognition of exported templates. This feature of C++03 templates was removed in C++11, and is not enabled by default. This option is valid only in C++ mode. This option requires that dependent name processing be done, and cannot be used with implicit inclusion of template definitions. |
--extern_inline--no_extern_inline |
Enable or disable support for |
--fixed_point--no_fixed_point |
Enable or disable support for Embedded C fixed-point types. (Not available in C++ modes.) |
--inline |
Enable recognition of the C99 |
--lambdas--no_lambdas |
Enable or disable support for C++11 lambdas. (Only available in C++ modes.) |
|
Permit the use of |
--modules--no_modules |
Enable or disable support for modules. Modules are currently experimental and will be enabled by default in future releases in the applicable modes. The front end does not currently generate modules files of its own and can only consume module files produced by Microsoft Visual Studio version 16.8. This support is incomplete and compatibility will change in future releases. |
--multibyte_chars--no_multibyte_chars |
Enable or disable processing for multibyte character sequences in comments, string literals, and character constants. Multibyte encodings are used for character sets like the Japanese SJIS. |
--named_address_spaces--no_named_address_spaces |
Enable or disable support for Embedded C named address space qualifiers. (Not available in C++ modes.) |
--named_registers--no_named_registers |
Enable or disable support for Embedded C named-register storage class specifiers. (Not available in C++ modes.) |
--namespaces--no_namespaces |
Enable or disable support for namespaces. This option is valid only in C++ mode. |
--nonstd_using_decl--no_nonstd_using_decl |
In C++, controls whether a nonmember using-declaration that specifies an unqualified name is allowed. |
--nullptr--no_nullptr |
Enable or disable support for the C++11 |
--old_specializations--no_old_specializations |
Enable or disable acceptance of old-style template specializations
(i.e., specializations that do not use the |
--relaxed_abstract_checking--no_relaxed_abstract_checking |
Enable or disable a mode in which checking for the use abstract class types as function parameter or return types is performed only when the function is defined or called. Traditionally this checking has been performed on non-defining function declarations as well, and this behavior can be preserved via the second option. |
--restrict--no_restrict |
Enable or disable recognition of the |
--rtti--no_rtti |
Enable or disable support for RTTI (runtime type information)
features: |
--rvalue_ctor_is_copy_ctor--rvalue_ctor_is_not_copy_ctor |
Determines whether an rvalue (or “move”) constructor is treated as a copy constructor (the default) or not. If rvalue constructors are treated as copy constructors, a user-declared rvalue constructor will inhibit the implicit generation of a traditional copy constructor. |
--rvalue_refs--no_rvalue_refs |
Enable or disable support for rvalue references. (Only valid in C++ mode.) |
--sun_linker_scope--no_sun_linker_scope |
Enable or disable support for Sun CC 5.5 link scope specifiers
( |
--thread_local_storage--no_thread_local_storage |
Enable or disable the C++11 |
--trigraphs--no_trigraphs |
Enable or disable recognition of trigraphs. |
--typename--no_typename |
Enable or disable recognition of |
--type_traits_helpers--no_type_traits_helpers |
Enable or disable support for type traits helpers (like |
--uliterals--no_uliterals |
Enable or disable recognition of U-literals (string
literals of the forms |
--unrestricted_unions--no_unrestricted_unions |
Enable or disable C++11-style “unrestricted unions” (i.e., unions with data members that have nontrivial initialization and/or destruction semantics). This option can currently not be enabled in Microsoft mode. |
--user_defined_literals--no_user_defined_literals |
Enable or disable C++11-style “user-defined literals,” i.e., literals
with a suffix designating an operator function that is to be called to
produce the value of the literal, e.g., |
--utf8_char_literals--no_utf8_char_literals |
Enable or disable C++17-style |
--variadic_macros--no_variadic_macros |
Enable or disable support for variadic macros (a C99 feature that is also available in C++ mode). |
--extended_variadic_macros--no_extended_variadic_macros |
Enable or disable support for “extended variadic macros,” an extension that emulates the behavior of certain other C compilers when it comes to variadic macros. |
--variadic_templates--no_variadic_templates |
Enable or disable support for “variadic templates,” a C++11 feature that allows declaration of templates with a variable number of arguments. The default value is dependent on the major language mode. This option is valid only in C++ modes. |
--vla--no_vla |
Enable or disable support for “variable length arrays,” a C99 feature and an extension in some other modes that allows the declaration and use of arrays of automatic storage duration with dimensions that are fixed at run time. |
--wchar_t_keyword--no_wchar_t_keyword |
Enable or disable recognition of |
Alternative Language Behaviors¶
The following options affect the meaning of various language constructs.
--aligned_new--no_aligned_new |
Enable or disable calling special allocation and deallocation functions for types with more stringent alignment requirements than the fundamental types (enabled by default in C++17 modes and disabled otherwise). |
--arg_dep_lookup--no_arg_dep_lookup |
In C++, controls whether argument dependent lookup of unqualified function names is performed. |
--base_assign_op_is_default--no_base_assign_op_is_default |
Enable or disable the anachronism of accepting a copy assignment operator that has an input parameter that is a reference to a base class as a default copy assignment operator for the derived class. This option is enabled by default in cfront compatibility mode. |
--class_name_injection--no_class_name_injection |
In C++, controls whether the name of a class is injected into the scope of the class (as required by the standard) or is not injected (as was true in earlier versions of the C++ language). |
--const_string_literals--no_const_string_literals |
Control whether C++ string literals and wide string literals are const (as required by the standard) or non-const (as was true in earlier versions of the C++ language). |
|
The calling convention that should be assumed for functions that are
declared without an explicit calling convention. calling-convention must
be one of |
--default_nocommon_tentative_definitions--default_common_tentative_definitions |
Control whether tentative definitions are placed in “common” storage. The default can be overridden for specific variables with the GNU attributes “common” and “nocommon”. |
--defer_parse_function_templates--no_defer_parse_function_templates |
Enable or disable deferral of prototype instantiations until the first
actual instantiation of a function. This is used to permit the
compilation of programs that contain definitions of unusable function
templates. It is enabled by default in permissive Microsoft mode (without
|
--dep_name--no_dep_name |
Enable or disable dependent name processing; i.e., the
special lookup of names used in templates as required by the C++
standard. This option is valid only in C++ mode
and |
--enum_overloading--no_enum_overloading |
Enable or disable support for using operator functions to overload builtin operations on enum-typed operands. |
--far_data_pointers--near_data_pointers--far_code_pointers--near_code_pointers |
Set the default size for pointers when support for
|
--friend_injection--no_friend_injection |
In C++, controls whether the name of a class or function that is declared only in friend declarations is visible when using the normal lookup mechanisms. When friend names are injected, they are visible to such lookups. When friend names are not injected (as required by the standard), function names are visible only when using argument-dependent lookup, and class names are never visible. |
--func_prototype_tags--no_func_prototype_tags |
In C, controls whether tag types first declared in a function prototype belong to the function prototype scope (standard C behavior) or to a surrounding scope (default Microsoft C behavior). |
|
Use the GNU C89 semantics of |
--gen_move_operations--no_gen_move_operations |
Enable or disable the generation of move constructors and move assignment operators according to standard C++11 rules. |
--guiding_decls--no_guiding_decls |
Enable or disable recognition of “guiding declarations” of template functions. A guiding declaration is a function declaration that matches an instance of a function template but has no explicit definition (since its definition derives from the function template). For example: template <class T> void f(T) { ... }
void f(int);
When regarded as a guiding declaration, |
|
Enable a |
--implicit_extern_c_type_conversion--no_implicit_extern_c_type_conversion |
Enable or disable an extension to permit implicit type conversion in C++
between a pointer to an |
--implicit_noexcept--no_implicit_noexcept |
Enable or disable the implicit generation of exception specifications for user-declared destructors and deallocation functions in C++11 mode. (In strict C++11 mode, it is enabled by default, whereas in other C++11 modes it is disabled by default.) |
--implicit_typename--no_implicit_typename |
Enable or disable implicit determination, from context, whether a template parameter dependent name is a type or nontype. This option is valid only in C++ mode. |
--late_tiebreaker--early_tiebreaker |
Select the way that tie-breakers (e.g., cv-qualifier differences) apply in overload resolution. In “early” tie-breaker processing, the tie-breakers are considered at the same time as other measures of the goodness of the match of an argument value and the corresponding parameter type (this is the standard approach). In “late” tiebreaker processing, tie-breakers are ignored during the initial comparison, and considered only if two functions are otherwise equally good on all arguments; the tie-breakers can then be used to choose one function over another. |
--long_lifetime_temps--short_lifetime_temps |
Select the lifetime for temporaries: “short” means to end of full expression; “long” means to the earliest of end of scope, end of switch clause, or the next label. “short” is standard C++, and “long” is what cfront uses (the cfront compatibility modes select “long” by default). |
--long_preserving_rules--no_long_preserving_rules |
Enable or disable the K&R usual arithmetic conversion rules with respect
to |
--max_depth_constexpr_call=<n>--max_cost_constexpr_call=<n> |
Specify the maximum depth of recursion or the maximum “cost” for folding
a top-level |
--ms_rvalue_cast--no_ms_rvalue_cast |
Explicitly disable or enable treating a cast of an lvalue to its own
type as that same lvalue. ( |
--ms_strict_ternary--no_ms_strict_ternary |
Enable or disable strict standard-conforming behavior of the conditional
ternary operator (?:) in Microsoft mode. It is disabled by default in
Microsoft mode, unless Microsoft permissive mode is disabled (see
|
--nonconst_ref_anachronism--no_nonconst_ref_anachronism |
Enable or disable the anachronism of allowing a reference to nonconst to
bind to a class rvalue of the right type. This anachronism is also
enabled by the |
--nonstd_anonymous_unions--no_nonstd_anonymous_unions |
Enable or disable extensions to the C++ anonymous union feature (including of anonymous “structs” or “classes”). This option can also be used in C modes. Enabled by default in GNU and Microsoft modes, and disabled by default in strict modes. |
--nonstd_default_arg_deduction--no_nonstd_default_arg_deduction |
Controls whether default arguments are retained as part of deduced function types. The C++ standard requires that default arguments not be part of deduced function types. |
--nonstd_instantiation_lookup--no_nonstd_instantiation_lookup |
Controls whether the lookup of names during template instantiation should, instead of the normal lookup rules, use rules that were part of the C++98 working paper for some time during the development of the standard. In this mode, names are looked up in both the namespace of the template definition and in the namespace in which a template entity was first referenced in a way that would require an instantiation. |
--nonstd_qualifier_deduction--no_nonstd_qualifier_deduction |
Controls whether nonstandard template argument deduction should be
performed in the qualifier portion of a qualified name. With this
feature enabled, a template argument for the template parameter T can de
deduced in contexts like |
--old_id_chars--no_old_id_chars |
Controls whether the set of extended characters accepted in C++ identifiers should be those specified by pre-C++23 C++ standards or by Unicode Standard Annex #44. The latter is the default in all C++ modes, because the C++ Standard Committee adopted the Unicode specification of identifier characters both for C++23 and retroactively for earlier standards. |
--old_for_init--new_for_init |
Control the scope of a declaration in a
|
|
Set the default alignment for packing classes and
structs to n, a power-of-2 value between 1 and 32768. The
argument n is the default maximum alignment for nonstatic data
members; it can be overridden by a |
--parse_templates--no_parse_templates |
Enable or disable the parsing of nonclass templates in their generic form (i.e., even if they are not really instantiated). It is done by default if dependent name processing is enabled. This option is valid only in C++ mode. Note that if you disable parsing of templates, the IR will be missing some information about templates (even if they are instantiated). This will lead to some analysis rules not reporting any violations in templates. |
--preserve_lvalues_with_same_type_casts--no_preserve_lvalues_with_same_type_casts |
Explicitly enable or disable treating a cast of an lvalue to its own type as that same lvalue (whereas both C and C++ specify that such casts result in rvalues). Enabled by default in Microsoft and Sun modes. |
--short_enums--no_short_enums |
Enable or disable a mode in which all enumeration types are ‘‘packed’’ (meaning that the underlying type of the enumeration is chosen to be the smallest integer that will accommodate the enumerator constants). Only valid in GNU C compatibility mode. |
|
Make bit fields declared with a plain integer type (e.g., |
--signed_chars-s |
Make plain |
--special_subscript_cost--no_special_subscript_cost |
Enable or disable a special nonstandard weighting of the conversion to
the integral operand of the struct A {
A();
operator int *();
int operator[](unsigned);
};
void main() {
A a;
a[0]; // Ambiguous, but allowed with this option
// operator[] is chosen
}
As of July 1996, the above is again acceptable, if |
--stdarg_builtin--no_stdarg_builtin |
Enable or disable special treatment of the |
|
Make bit fields declared with a plain integer type (e.g., |
--unsigned_chars-u |
Make plain |
--using_std--no_using_std |
Enable or disable implicit use of the |
Template Instantiation Options¶
--auto_instantiation--no_auto_instantiation-T |
Enable or disable automatic instantiation of templates. The |
|
This option specifies the name of the template definition list file passed between the front end and the prelinker. This file is a temporary file and does not remain after the compilation is complete. This option is supplied for use by the driver program that invokes the front end and is not intended to be used by end-users. |
|
This option specifies the name to be used for the exported template file used for processing of exported templates. This option is supplied for use by the driver program that invokes the front end and is not intended to be used by end-users. |
|
This option specifies the name to be used for the template instantiation request file used in automatic instantiation mode. This option is supplied for use by the driver program that invokes the front end and is not intended to be used by end-users. |
--implicit_include--no_implicit_include |
Enable or disable implicit inclusion of source files as a method of finding definitions of template entities to be instantiated. See the section of this chapter on template instantiation. This option is valid only in C++ mode. |
--instantiate <mode>-t<mode> |
Control instantiation of external template entities. External template entities are external (i.e., noninline and nonstatic) template functions, variables, and template static data members. The instantiation mode determines the template entities for which code should be generated based on the template definition):
See the section of this chapter on template instantiation. This option is valid only in C++ mode. |
|
Specifies the maximum number of instantiations of a given template that may be in process of being instantiated at a given time. This is used to detect runaway recursive instantiations. If n is zero, there is no limit. The default is 1024. |
|
When automatic instantiation is being used, this option suppresses the generation of the special symbols used by the prelinker to do automatic instantiation processing. This option is for use by the driver and prelinker and should not be used directly by users. This option is used by to implement the driver option that removes the instantiation flags from object files once the prelinking step has completed. |
|
Specifies a directory name to be placed on the exported template search path. The directories are used to find the definitions of exported templates and are searched in the order in which they are specified on the command-line. The current directory is always the first entry on the search path. |
|
This option specifies the name to be used for the template instantiation information file used in automatic instantiation mode. This option is supplied for use by the driver program that invokes the front end and is not intended to be used by end-users. |
Code Generation Options¶
The following options control the IL produced.
--no_code_gen-n |
Do syntax-checking only, i.e., do not run the back end. |
|
Force definition of virtual function tables in cases where
the heuristic used by the front end to decide on definition of virtual
function tables provides no guidance. See |
--keep_restrict_in_signatures--no_keep_restrict_in_signatures |
In most modern configurations, top-level parameter type qualifiers are removed from function types. In such configurations, this option overrides or preserves that behavior for the restrict qualifier; i.e., when the option is enabled, the mangled name of a function will reflect the presence of top-level restrict parameter type qualifiers. |
--remove_unneeded_entities--no_remove_unneeded_entities |
Enable or disable an optimization to prune the IL tree of types, variables, routines, and related IL entries that are not “really needed.” (Something may be referenced but unneeded if is referenced only by something that is itself unneeded; certain entities, such as global variables and routines defined in the translation unit, are always considered to be needed.) |
--suppress_vtbl-V |
Suppress definition of virtual function tables in cases where the
heuristic used by the front end to decide on definition of virtual
function tables provides no guidance. The virtual function table for a
class is defined in a compilation if the compilation contains a
definition of the first non-inline non-pure virtual function of the
class. For classes that contain no such function, the default behavior
is to define the virtual function table (but to define it as a local
static entity). The option |
Precompiled Header Options¶
The following options control how precompiled header files are generated and used.
|
Automatically use and/or create a precompiled header file — for
details, see the “Precompiled Headers” section in this chapter. If
|
|
If other conditions are satisfied (see the
“Precompiled Headers” section), create a precompiled header file with
the specified name. If |
|
Use a precompiled header file of the specified
name as part of the current compilation. If |
|
The directory in which to search for and/or
create a precompiled header file. This option may be used with automatic
PCH mode ( |
--pch_messages--no_pch_messages |
Enable or disable the display of a message indicating that a precompiled header file was created or used in the current compilation. |
|
In automatic PCH mode, for each precompiled header file that cannot be used for the current compilation, a message is displayed giving the reason that the file cannot be used. |
C++/CLI Options¶
|
Use the given assembly metadata file instead of |
|
Import the given assembly metadata file prior to
processing the input source (but after importing |
|
Add the given directory to the search path used when searching for assembly metadata files. |
|
Do or do not implicitly include the installation directory of the Microsoft .NET runtime in the search path used when searching for assembly metadata files. The default is to include that directory. |
|
Search for the |
Miscellaneous Options¶
--version-v |
Display the version number of the front end, and the Edison Design Group copyright. |
|
Used to indicate that the EDG runtime library is being compiled. This causes additional macros to be predefined that are used to pass target configuration information from the front end to the runtime. |
|
Display the complete set of |
|
Display the complete set of configuration macros with which the front
end was built. The output (to the error output file) can be captured
and used as the contents of the |
|
Displays the legacy configuration in such a manner that the
configuration can be used to specify a new target configuration named
target-config-name. For customers who have multiple versions of the
front end (each configured for a specific target), this option can be
used to generate a separate target configuration for each of the legacy
configurations, and the output combined to form a single configuration
where the target can be specified at run-time (via the |
--incognito--no_incognito |
Enable or disable the suppression of implicitly-defined EDG-specific macros such
as |
|
Specify the fixed address to be used in calls
to |
--check_unicode_security--no_check_unicode_security |
Enable or disable checking of comments, string literals, and identifiers for Unicode patterns that could be used to disguise malicious source code by making it appear innocuous; suspicious patterns are reported as warnings. Checking is only applicable to UTF-encoded Unicode source and header files. |
--module_import_diagnostics--no_module_import_diagnostics |
Enable or disable the issuing of diagnostic messages during the import of entities from a module. The option can be used to reduce verbosity and condense diagnostics that do not relate to the source file being compiled. The default setting is: disabled. |
|
Specify the directory to use in expanding relative path names. All relative paths
are expanded after command-line processing is complete, so that any |
Environment Variables¶
On Windows, the
environment variable TMP is used to specify the directory to be used for
temporary files. If TMP is not set, and on platforms other than Windows,
the environment variable TMPDIR is used to indicate a directory to
be used for temporary files. If TMPDIR is not set, a default temporary
directory (often, /tmp) is used.
The cafe compiler frontend does not make direct use of environment variables like
INCLUDE, C_INCLUDE_PATH or CPATH. However, the compiler configuration
may do so. See e.g. option language_c.preprocessing.sys_include_envvar of the
compiler toolchain configuration.
Diagnostic Messages¶
Diagnostic messages have an associated severity, as follows:
Catastrophic errors indicate problems of such severity that the compilation cannot continue. For example: command-line errors, internal errors, and missing include files. If multiple source files are being compiled, any source files after the current one will not be compiled.
Errors indicate violations of the syntax or semantic rules of the C or C++ language. Compilation continues, but object code is not generated.
Warnings indicate something valid but questionable. Compilation continues and object code is generated (if no errors are detected).
Remarks indicate something that is valid and probably intended, but which a careful programmer may want to check. These diagnostics are not issued by default. Compilation continues and object code is generated (if no errors are detected).
Diagnostics are written to the error output file with a form like the following:
"test.c", line 5: a break statement may only be used within a loop
or switch
break;
^
Diagnostics are normally written to stderr. Errors during command-line
processing are always directed to stderr.
Diagnostic messages can optionally be “colorized”. Colorization is
enabled with the --color switch. When colorization is enabled,
format_output_line replaces the annotations with Select Graphic
Rendition (SGR) codes that, on most terminal emulators, can be used to
highlight text in various ways. The SGR codes used for colorization
can be overridden by the EDG_COLORS environment variable (if set). The string
consists of a colon-separated list of elements, where each element
specifies a string that maps to an a_diagnostic_annotation_kind value
followed by an “=” and the SGR string to use when highlighting text of
that kind. For example:
"error=01;31:warning=01;35:note=01;36:locus=01:quote=01:range1=32"
Note that the message identifies the file and line involved, and that
the source line itself (with position indicated by the ^) follows the
message. If there are several diagnostics in one source line, each
diagnostic will have the form above, with the result that the text of
the source line will be displayed several times, with an appropriate
position each time.
Long messages are wrapped to additional lines when necessary.
A configuration flag controls whether or not the string “error:” appears, i.e., the front end can be configured so that the severity string is omitted when the severity is “error”.
A command line option may be used to request a shorter form of the diagnostic output in which the original source line is not displayed and the error message text is not wrapped when too long to fit on a single line.
A command line option may be used to request that the error number be
included in the diagnostic message. When displayed, the error number
also indicates whether the error may have its severity overridden on the
command line. If the severity may be overridden, the error number will
include the suffix -D (for “discretionary”); otherwise no suffix will
be present.
"Test_name.c", line 7: error #64-D: declaration does not declare anything
struct {};
^
"Test_name.c", line 9: error #77: this declaration has no storage class or type specifier
xxxxx;
^
Because an error is determined to be discretionary based on the error severity associated with a specific context, a given error may be discretionary in some cases and not in others.
For some messages, a list of entities is useful; they are listed following the initial error message:
"test.c", line 4: error: more than one instance of overloaded function "f" matches the argument list:
function "f(int)"
function "f(float)"
argument types are: (double)
f(1.5);
^
In some cases, some additional context information is provided; specifically, such context information is useful when the front end issues a diagnostic while doing a template instantiation or while generating a constructor, destructor, or assignment operator function. For example:
"test.c", line 7: error: "A::A()" is inaccessible
B x;
^
detected during implicit generation of "B::B()" at line 7
Without the context information, it is very hard to figure out what the error refers to.
Messages referring
to text occurring inside a macro expansion may provide additional
information. This additional information gives the source location from
which the text was copied into the macro expansion (i.e., from a macro
definition or one of the arguments in the top-level macro invocation),
as well as possibly the chain of macro invocations leading to the
expanded text to which the diagnostic refers.
The display of this information can also be
enabled or disabled by the command-line option
--[no_]macro_positions_in_diagnostics. The information is presented in a
form like the following:
"test.c", line 1: error: identifier "val" is undefined
#define incr(x) (x)+=val
^
in expansion of macro "incr" at "test.c", line 2,
in expansion of macro "next_val" at "test.c", line 4:
return next_val(i);
^
Termination Messages¶
When the front end writes sign-off messages to the error output file. For example, one of the following forms of message
nerrors detected in the compilation of“ifile”.1 catastrophic error detected in the compilation of“ifile”.nerrors and 1 catastrophic error detected in the compilation of“ifile”.
is written to indicate the detection of errors in the compilation. No message is written if no errors were detected. The following message
Error limit reached.
is written when the count of errors reaches the error limit (see the -e option, above); compilation is then terminated. The message
Compilation terminated.
is written at the end of a compilation that was prematurely terminated because of a catastrophic error. The message
Compilation aborted.
is written at the end of a compilation that was prematurely terminated because of an internal error. Such an error indicates an internal problem in the compiler and should be reported to those responsible for its maintenance.
Response to Signals¶
The signals SIGINT (caused by a user interrupt, like ^C) and
SIGTERM (caused by a kill command) are trapped by the front end and
cause abnormal termination.
Exit Status¶
On completion, the front end returns with a code indicating the highest-severity diagnostic detected: 4 if there was a catastrophic error, 2 if there were any errors, or 0 if there were any warnings or remarks or if there were no diagnostics of any kind.
If multiple source files are compiled, the exit status indicates the highest-severity diagnostic detected in the entire compilation.
Finding Include Files¶
A file name specified in a #include directive is searched for in a set
of directories specified by command-line options and environment
variables. If the file name specified does not include a suffix, a set
of suffixes is used when searching for the file.
Files whose names are not absolute pathnames and that are enclosed in
"..." will be searched for in the following directories, in the order
listed:
The directory containing the current input file (the primary source file or the file containing the
#include); [1]any directories specified in
--include_directoryoptions (in the order in which they were listed on the command line);any directories on the standard list (this list is selected at the time of installation of the front end; often, it is just the one directory
/usr/includeor a similar system include directory for C++).
For file names enclosed in <...>, only the directories that are
specified using the --include_directory option and those on the standard
list are searched. If the directory name is specified as -, e.g.,
-I-, the option indicates the point in the list of --include_directory
options at which the search for file names enclosed in <...> should
begin. That is, the search for <...> names should only consider
directories named in --include_directory options following the -I-, and
the directories of item 3 above. -I- also removes the directory
containing the current input file (item 1 above) from the search path
for file names enclosed in "...".
An include directory specified with the --sys_include option is
considered a “system” include directory. Warnings are suppressed when
processing files found in system include directories. If a default
include directory has been specified using the USR_INCLUDE configuration
flag or environment variable, it is considered a system include
directory.
If the file name has no suffix it will be searched for by appending each
of a set of include file suffixes. When searching in a given directory
all of the suffixes are tried in that directory before moving on to the
next search directory. The default is that no suffix will be appended.
Suffixes can be specified using the --incl_suffixes command-line option.
A null
file suffix cannot be used unless it is present in the suffix list
(i.e., the front end will always attempt to add a suffix from the suffix
list when the file name has no suffix).
Finding Module Files¶
An import directive can specify either a module unit or a header unit,
and the process of finding these differ. A header unit import names
the header identically to the equivalent #include directive (a file
name enclosed in <...> or "..."), while a module unit is imported by
its name and not the name of the file containing the module unit.
An import directive that specifies a header unit first finds the
named header using the process for finding #include files. See
section finding-include-files. If the header is found, the
corresponding module file is found by the following search, in the
listed order:
Using the direct mappings provided by
--ms_header_unit.Using the unresolved mappings provided by
--ms_header_unit_angle(if the header file name is specified via<...>) or by--ms_header_unit_quote(if the header file name is specified via"..."). If a match is found here, that match is added to the map for--ms_header_unit.
An import directive that specifies a module unit will search for the module file, in the order listed:
Any direct mappings from that module name to a module file as specified by
--ms_mod_file_mapAny files listed without a direct map by
--ms_mod_file_map, examining those files to determine if the module each represents matches the module being importedFiles in the directory containing the current input file (the primary source file or the file containing the import)
Files in any directories specified by
--modules_directory(in the order in which they were listed on the command line)Files in the directory specified by the
EDG_MODULES_PATHenvironment variable, if it’s set.
C++ Dialect Accepted¶
In strict C++ mode, the front end accepts the complete C++ language as defined by the ISO/IEC 14882:2003 standard, including export templates (if the front end’s configuration allows them). In nonstrict C++ mode (which is the default in common configurations), a small set of features—particularly, export templates—are not supported, but some minor extensions commonly available on other compilers are accepted.
The front end accepts the complete C++17 language as defined by the
ISO/IEC 14882:2017 standard (enabled through the command-line option
--c++17). The front end also fully supports the earlier C++14,
C++11, and (as noted above) C++98/03 versions of the language.
Extensive compatibility modes are also available for the Microsoft
Visual C++ compilers, the GNU C++ (“GCC”) compilers, and the clang C++
compiler. A more basic Sun C++ compatibility mode is also implemented.
Only one emulation mode may be active at a time (but --ms_extensions
or --ms_compatibility may be enabled in non-Microsoft emulation modes).
The front end also has a cfront compatibility mode, which duplicates a number of “features” and bugs of cfront 2.1 and 3.0.x. Complete compatibility is not guaranteed or intended—the mode is there to allow programmers who have unwittingly used cfront features to continue to compile their existing code. In particular, if a program gets an error when compiled by cfront, the EDG front end may produce a different error or no error at all.
Command-line options are available to enable and disable anachronisms, to control strict standard-conformance checking, and to adjust the severity of certain diagnostics.
C++20 Implementation Status¶
Most of the new features and changes in the C++20 standard are accepted by the front end. Details about the specific changes (e.g., the first version of the front end to support the feature, and the standard committee papers that introduced the feature) can be found on the EDG website. See https://www.edg.com/c/features.
The following C++20 features are not yet supported (our web site has links with further details):
Concepts are supported, but some of the most recent changes to the feature are not yet supported:
Partial ordering of rewritten operator candidates resulting from constrained templates
Clarify declaration matching and partial ordering requiring substitution into constraints
When are constexpr member functions defined? (core issue 1581). This is not yet implemented because of concerns about potential code breakage.
Modules.
C++23 Implementation Status¶
Some of the new features and changes in the draft C++23 standard are accepted by the front end. Details about the specific changes (e.g., the first version of the front end to support the feature, and the standard committee papers that introduced the feature) can be found on the EDG website. See https://www.edg.com/c/features.
Anachronisms Accepted¶
The following anachronisms are accepted when anachronisms are enabled:
overloadis allowed in function declarations. It is accepted and ignored.Definitions are not required for static data members that can be initialized using default initialization. The anachronism does not apply to static data members of template classes; they must always be defined.
The number of elements in an array may be specified in an array
deleteoperation. The value is ignored.A single
operator++()andoperator--()function can be used to overload both prefix and postfix operations.The base class name may be omitted in a base class initializer if there is only one immediate base class.
Assignment to
thisin constructors and destructors is allowed. This is allowed only if anachronisms are enabled and the “assignment tothis” configuration parameter is enabled.A bound function pointer (a pointer to a member function for a given object) can be cast to a pointer to a function.
A nested class name may be used as a nonnested class name provided no other class of that name has been declared. The anachronism is not applied to template classes.
A reference to a non-const type may be initialized from a value of a different type. A temporary is created, it is initialized from the (converted) initial value, and the reference is set to the temporary.
A reference to a non-const class type may be initialized from an rvalue of the class type or a derived class thereof. No (additional) temporary is used.
A function with old-style parameter declarations is allowed and may participate in function overloading as though it were prototyped. Default argument promotion is not applied to parameter types of such functions when the check for compatibility is done, so that the following declares the overloading of two functions named
f:int f(int); int f(x) char x; { return x; }
It will be noted that in C this code is legal but has a different meaning: a tentative declaration of f is followed by its definition.
When
--nonconst_ref_anachronismis enabled, a reference to a nonconst class can be bound to a class rvalue of the same type or a derived type thereof.struct A { A(int); A operator=(A&); A operator+(const A&); }; main () { A b(1); b = A(1) + A(2); // Allowed as anachronism }
“Default” C++ Mode¶
The following extensions are accepted default C++ mode. Most of these are also accepted in any other C++ mode that does not diagnose strict ANSI violations as errors (exceptions are explicitly noted).
A
frienddeclaration for aclassmay omit the class keyword:class B; class A { friend B; // Should be "friend class B" };
Constants of scalar type may be defined within classes (this is an old form; the modern form uses an initialized static data member):
class A { const int size = 10; int a[size]; };
In the declaration of a class member, a qualified name may be used:
struct A { int A::f(); // Should be int f(); };
An extension is supported to allow an anonymous union to be introduced into a containing class by a
typedefname — it needn’t be declared directly, as with a true anonymous union. For example:typedef union { int i, j; } U; // U identifies a reusable anonymous union. class A { U; // Okay -- references to A::i and A::j are allowed. };
In addition, the extension also permits “anonymous classes” and “anonymous structs,” as long as they have no C++ features (e.g., no static data members or member functions and no nonpublic members) and have no nested types other than other anonymous classes, structs, or unions. For instance,
struct A { struct { int i, j; }; // Okay -- references to A::i and A::j are allowed. };
If recognition of the
restrictkeyword is enabled, the C99restrictfeature is supported in a form extended for C++, which allowsrestrictas a type qualifier for reference and pointer-to-member types and for nonstatic member functions. The set of C++ extensions is described in J16/92-0057.Implicit type conversion between a pointer to an
extern "C"function and a pointer to anextern "C++"function is permitted. Here’s an example:extern "C" void f(); // f’s type has extern "C" linkage void (*pf)() // pf points to an extern "C++" function = &f; // error unless implicit conversion is allowed
This extension is allowed in environments where C and C++ functions share the same calling conventions. It is enabled by default unless strict ANSI mode is enabled; it can also be enabled in with command-line option
--implicit_extern_c_type_conversion.A
?operator whose second and third operands are string literals or wide string literals can be implicitly converted tochar *orwchar_t *. (Recall that in C++ string literals are const. There is a deprecated implicit conversion that allows conversion of a string literal tochar *, dropping the const. That conversion, however, applies only to simple string literals. Allowing it for the result of a?operation is an extension.)Default arguments may be specified for function parameters other than those of a top-level function declaration (e.g., they are accepted on
typedefdeclarations and on pointer-to-function and pointer-to-member-function declarations).Nonstatic local variables of an enclosing function can be referenced in a non-evaluated expression (e.g., a
sizeofexpression) inside a local class. A warning is issued.In default C++ mode (but not other non-C++11 modes), the friend class syntax is extended to allow nonclass types as well as class types expressed through a typedef or without an elaborated type name. For example:
typedef struct S ST; class C { friend S; // Okay (requires S to be in scope). friend ST; // Okay (same as "friend S;"). friend int; // Okay (no effect). friend S const; // Error: cv-qualifiers cannot appear directly. };
In default C++ mode, mixed string literal concatenations are accepted. (This is a feature carried over from C99 and also available in GNU modes. It is not enabled in other non-C++11 modes.)
wchar_t *str = "a" L"b"; // Okay, same as L"ab".
In default C++ mode, variadic macros are accepted. (This is a feature carried over from C99 and also available in GNU modes. It is not by default enabled in other non-C++11 modes.)
In default C++ mode, empty macro arguments are accepted (a feature carried over from C99).
A trailing comma in the definition of an enumeration type is silently accepted (a feature carried over from C99):
enum E { e, };
Except where noted, all of the extensions described in the C dialect section are also allowed in C++ mode.
GNU C++ Mode¶
In GNU C++ mode, a large number of extensions and bugs are closely emulated. This feature enables the front end to compile many large and complex projects that were developed using the GNU tool chain; this includes major open-source projects.
Support for this emulation is ongoing: New GNU C++ features are added as needed, with priority given to features used in system headers.
Because the GNU compiler frequently changes behavior between releases,
the front end provides an option (--gnu_version) to specify a specific
version of GCC to emulate. Generally speaking, features and bugs are
emulated to exactly match each known version of GCC, but occasionally
the emulation is approximate and in such cases the front end is often a
little more permissive than GCC on the principle that it is more
important to accept source that GCC accepts than to diagnose every case
that GCC diagnoses. The front end does not, however, attempt to emulate
every GCC command-line option; in particular, GCC options to be
extra-permissive are not emulated (however, the severity of specific
error diagnostics can sometimes be decreased to accept constructs that
are not by-default allowed in GNU emulation mode).
Some GNU features are only emulated when specific configuration options are enabled. For example, support for complex floating-point types is only available when the front end is configured to support C99 extensions.
A few GCC extensions there are likely not going to be supported in the foreseeable future:
The forward declaration of function parameters (so they can participate in variable-length array parameters).
GNU-style complex integral types (complex floating-point types are supported)
Nested functions
Local structs with variable-length array fields. Such fields are treated (with a warning) as zero-length arrays in GNU C mode, which is a useful approximation in some circumstances, but not generally equivalent to the GNU feature.
Microsoft C++ Mode¶
The front end also extensively emulates the Microsoft Visual C++
compilers. As is the case with GNU modes, an option
(--microsoft_version) is available to select a specific version of
Microsoft’s compiler to emulate.
Although Microsoft C++ and C modes generally emulate both
extensions/features and bugs, the emulation of a certain class of bugs
(considered more severe) can be controlled separately (using the
--no_microsoft_bugs/--microsoft_bugs options).
Microsoft C++ mode can be combined with certain other language options to enable a larger superset of the language accepted by the Microsoft compiler.
In addition to full Microsoft emulation mode, two subsets of Microsoft
emulation are available: --ms_extensions, and --ms_compatibility,
corresponding to clang’s -fms-extensions and -fms-compatibility
command-line options, respectively. These command-line options allow a
certain degree of Microsoft emulation while the primary emulation mode
is something else (e.g., --clang).
Support for Microsoft C++ emulation is ongoing: New features are added as needed, with priority given to features used in system headers.
Microsoft C++/CLI Mode¶
The front end implements the language extensions known as “C++/CLI” that simplifies writing C++-like programs for Microsoft’s “.NET” environment. These extensions are formally described through the ECMA-372 standard, but where the Microsoft compiler deviates from the standard, the front end follows the Microsoft compiler rather than the standard.
Almost all C++/CLI features are implemented in the front end. This
includes various managed class kinds and the special members (e.g.
properties) that they can contain, delegates, handles and tracking
references, gcnew, generics, importing of assemblies, hide-by-sig lookup
rules, string literal rules, and so forth. A notable exception is
Microsoft-style attributes (delimited by square brackets): The front end
can parse them, but does not currently implement their semantics.
An earlier attempt at integrating C++ and .NET was known as “Managed C++”: The front end does not support those earlier Microsoft compiler features (which have since been deprecated by Microsoft).
C Dialect Accepted¶
The front end accepts the ANSI/ISO C language as defined by ANSI/ISO 9899:1990. In C99 mode, it accepts the ANSI/ISO C language defined by ISO/IEC 9899:1999 as modified by Technical Corrigenda 1 through 3. In C11 mode, it accepts the C language defined by ISO/IEC 9899:2011 and in C18 mode the C language defined by ISO/IEC 9899:2018 (which only differs from C11 in minor ways). In C23 mode, many of the features of the latest anticipated draft standard have been implemented. See https://www.edg.com/c/features for up-to-date information about feature implementation.
The front end extensively emulates the C modes of the Microsoft, GNU,
and clang compilers. See section gnu-cxx-mode. As with C++ mode, only one
emulation mode may be in effect for a given compilation. The
--ms_extensions and --ms_compatibility options can be used to emulate
certain Microsoft behavior irrespective of the emulation mode.
There is no Sun C mode corresponding to Sun C++ mode, however.
The special comments recognized by the UNIX lint program — /*ARGSUSED*/,
/*VARARGS*/ (with or without a count of non-varying arguments), and
/*NOTREACHED*/ — are also recognized by the front end.
When Unified Parallel C (UPC) mode is enabled, it also accepts the core language extensions described in version 1.0 of the UPC Language Specifications.
C99 Features Available in Other Modes¶
Certain C language features were added in the C99 version of the ISO C standard and are supported in C99 mode. For a full list of those features, see ISO/IEC 9899:1999. A few features are noteworthy, however, because they are implementation-specific or because they can be enabled in older C modes or (when indicated) in C++ mode:
The options
‑‑variadic_macros,‑‑no_variadic_macros,‑‑extended_variadic_macrosand‑‑no_extended_variadic_macroscontrol whether macros taking a variable number of arguments are recognized. Configuration flags are available to select the default setting of these options; these are also available in C++ mode.Ordinary variadic macros (as included in C99) are illustrated by the following example:
#define OVM(x, ...) x(__VA_ARGS__) void f() { OVM(printf, "%s %d\n", "Three args for ", 1); } /* Expands to: printf("%s %d\n", "Three args for ", 1) */
During expansion the special identifier
__VA_ARGS__will be replaced by the trailing arguments of the macro invocation. If variadic macros are enabled, this special identifier can appear only in the replacement list of variadic macros.Extended variadic macros (as implemented by certain pre-C99 compilers) use a slightly different syntax and allow the name of the variadic parameter to be chosen (instead of
.../__VA_ARGS__):#define EVM(x, args...) x(args) void f() { EVM(printf, "%s %d\n", "Three args for ", 1); } /* Same expansion as previous example. */
In addition, enabling extended variadic macros adds a special behavior to the token pasting operator
##when it is followed by an empty or omitted macro argument: A preceding comma (possibly followed by white space) is erased. Hence,#define EVM2(fmt, args) printf(fmt , ## args) EVM2("Hello World\n")
expands to
printf("Hello Worldn")and the extraneous comma is erased.long longsupport:the
long longandunsigned long longtypes are accepted;integer constants suffixed by
LLare given the typelong long, and those suffixed byULLare given the typeunsigned long long(any of the suffix letters may be written in lower case);the specifier
%lldis recognized inprintfandscanfformatting strings; andthe
long longtypes are accommodated in the usual arithmetic conversions.
restrictmay be used as a type qualifier for object pointer types and function parameter arrays that decay to pointers. Its presence is recorded in the IL so that back ends can perform optimizations that would otherwise be prevented because of possible aliasing. The keyword is enabled by--restrict; this is also available in C++.Variable length arrays (VLAs) are supported. VLA types may appear only in the declaration of an identifier that belongs to a block or function-prototype scope. For example:
void addscalar(int n, int m, double a[n][m], double x) { int i, j; for (i=0; i<n; i++) for (j=0; j<m, j++) a[i][j] += x; /* a refers to a VLA with n*m elements. */ } double A[4][8]; void f() { addscalar(4, 8, A, 3.14); }
See also command line options
--vlaand--no_vla.Designators may be accepted in initializers for aggregates. See also command line options
‑‑designators,--no_designators,--extended_designatorsand--no_extended_designators.With
‑‑designators, designators of the forms.xand[k]are accepted. They can be concatenated to reach nested aggregate elements. For example:struct X { double a; int b[10] } x = { .b = { 1, [5] = 2 }, .b[3] = 1, .a = 42.0 };
In addition, with
--extended_designators, designators of the formx:and[m ... n]are accepted and the assignment (=) token becomes optional after array element designators. Field designators of the formx:cannot immediately be followed by an assignment token (=) or another designator. Examples:struct X { double a; int b[10] } x = { b: { 1, [5 ... 9] = 2 }, .b[7] 1, a: 42.0 }; struct Y y = { b:[3] /* Error */ = 7, a: = /* Error */ 42.0 };
Designators permit multiple initializations of the same subobject: only the last value is retained, but side-effects of prior initializing expressions do occur.
Compound literals are supported in expressions. For example,
int *p = (int []){1, 2, 3};
creates an unnamed lvalue of type
int[3]initialized as indicated.pis initialized to point to that array. Compound literals are not allowed in C++ mode.The
__genericpseudo-macro is implemented. This is an EDG extension used to support the type-generic math header<tgmath.h>. The form of the macro reference is:__generic(x, y, z, func_d, func_f, func_l, func_cd, func_cf, func_cl)
where
xand the optionalyandzare the arguments with which a type-generic function is called, and the remaining 6 arguments are the names of functions from which is selected the actual function to be called. The suffixes with which the function names are supplied here correspond to function parameter types ofdouble,float,long double,double _Complex,float _Complex, andlong double _Complex, respectively. The order is fixed. Function names may be omitted. For example,<tgmath.h>may have the following macros defined:#define sin(x) __generic(x,,, sin, sinf, sinl, csin, csinf,csinl)(x) #define fmax(x,y) __generic(x, y,,fmax, fmaxf, fmaxl,,,)(x, y) #define conjg(x) __generic(x,,, ,,, conjg, conjgf, conjgl)(x)
Note that sin and conjg take only one argument, that fmax has no forms that accept complex arguments, and that conjg has no forms that accept real arguments.
There is also a
__genericfxpseudo-macro that provides a similar capability for fixed-point types. The form of the macro reference is:__genericfx(x, fnc_hr, fnc_uhr, fnc_r, fnc_ur, fnc_lr, fnc_ulr, fnc_hk, fnc_uhk, fnc_k, fnc_uk, fnc_lk, fnc_ulk)
where
xis as above and the remaining 12 arguments are the names of functions, with the suffixes corresponding to function parameter types ofshort _Fract,unsigned short _Fract,_Fract,unsigned _Fract,long _Fract,unsigned long _Fract,short _Accum,unsigned short _Accum,_Accum,unsigned _Accum,long _Accum,unsigned long _Accum, respectively.The keywords
__I__,__NAN__, and__INFINITY__are defined as, respectively, a float_Imaginaryi, a float Not-a-Number, and a float positive Infinity. These are intended to be used by library writers to implement the C99 macrosI,NAN, andINFINITY.__NAN__and__INFINITY__are also available in all modes, not just C99 mode.A trailing array member of unspecified length in a struct type is called a flexible array member. Such members are a standard feature in C99. In default C99 mode (but not in strict C99 mode) trailing struct members can also have a type containing a flexible array member. For example:
struct F { int i; int f[]; // OK in default and strict C99 modes }; struct X { F x; // OK in default C99 mode (but not in strict mode) };
ANSI C Extensions¶
The following extensions are accepted (these are flagged if the -A or -a
option is specified):
A translation unit (input file) can contain no declarations.
Comment text can appear at the ends of preprocessing directives.
__ALIGNOF__(or__alignof__) is similar to sizeof, but returns the alignment requirement value for a type, or 1 if there is no alignment requirement. It may be followed by a type or expression in parentheses:__ALIGNOF__(type)__alignof__(type)__ALIGNOF__(expression)__alignof__(expression)The expression in the second form is not evaluated.
__INTADDR__(expression) scans the enclosed expression as a constant expression, and converts it to an integer constant (it is used in the offsetof macro).A number of “type traits pseudo-functions” (taking one or more type names) are accepted:
__has_nothrow_assign,__has_nothrow_constructor,__has_nothrow_copy,__has_nothrow_move_assign,__has_trivial_assign,__has_trivial_constructor,__has_trivial_copy,__has_trivial_destructor,__has_trivial_move_assign,__has_trivial_move_constructor,__has_virtual_destructor,__is_abstract,__is_base_of,__is_class,__is_constructible,__is_convertible_to,__is_destructible,__is_empty,__is_enum,__is_literal_type,__is_nothrow_assignable,__is_nothrow_constructible,__is_nothrow_destructible,__is_pod,__is_polymorphic,__is_standard_layout,__is_trivial,__is_trivially_assignable,__is_trivially_constructible,__is_trivially_copyable,__is_trivially_destructible, and__is_union.double x[__is_union(union U)]; // Okay.
These are silently accepted even in strict modes. They ease the implementation C++11 metaprogramming templates (many of which were first introduced by ISO/IEC TR 19768).
Bit fields may have base types that are
enums or integral types besidesintandunsigned int. This matches A.6.5.8 in the ANSI Common Extensions appendix.The address of a bit field may be taken if the bit field has the same size and alignment as one of the integral types. A warning is issued.
The last member of a
structmay have an incomplete array type. It may not be the only member of the struct (otherwise, the struct would have zero size).A file-scope array may have an incomplete
struct,union, orenumtype as its element type. The type must be completed before the array is subscripted (if it is), and by the end of the compilation if the array is notextern. In C++, an incompleteclassis also allowed.Static functions may be declared in function and block scopes. Their declarations are moved to the file scope.
enumtags may be incomplete: one may define the tag name and resolve it (by specifying the brace-enclosed list) later.The values of enumeration constants may be given by expressions that evaluate to unsigned quantities that fit in the
unsigned intrange but not in the int range. A warning is issued for suspicious cases.
/* When ints are 32 bits: */
enum a {w = -2147483648}; /* No warning */
enum b {x = 0x80000000}; /* No warning */
enum c {y = 0x80000001}; /* No warning */
enum d {z = 2147483649}; /* Warning */
An extra comma is allowed at the end of an
enumlist. A remark is issued except inpccmode.The final semicolon preceding the closing
}of a struct or union specifier may be omitted. A warning is issued except inpccmode.A label definition may be immediately followed by a right brace. (Normally, a statement must follow a label definition.) A warning is issued.
An empty declaration (a semicolon with nothing before it) is allowed. A remark is issued.
An initializer expression that is a single value and is used to initialize an entire static array, struct, or union need not be enclosed in braces. ANSI C requires the braces.
In an initializer, a pointer constant value may be cast to an integral type if the integral type is big enough to contain it.
The address of a variable with
registerstorage class may be taken. A warning is issued.In an integral constant expression, an integer constant may be cast to a pointer type and then back to an integral type.
long floatis accepted as a synonym fordouble.Pointers to incomplete arrays may be used in pointer addition, subtraction, and subscripting:
int (*p)[]; ... q = p[0];
A warning is issued if the value added or subtracted is anything other than a constant zero. Since the type pointed to by the pointer has zero size, the value added to or subtracted from the pointer is multiplied by zero and therefore has no effect on the result.
Benign redeclarations of
typedefnames are allowed. That is, a typedef name may be redeclared in the same scope as the same type. A warning is issued.Dollar signs can be accepted in identifiers through use of a command line option or by setting a configuration parameter. The default is to not allow dollar signs in identifiers.
Numbers are scanned according to the syntax for numbers rather than the pp-number syntax. Thus,
0x123e+1is scanned as three tokens instead of one invalid token. (If the-Aor-aoption is specified, of course, the pp-number syntax is used.)Assignment and pointer difference are allowed between pointers to types that are interchangeable but not identical, for example,
unsigned char *andchar *. This includes pointers to same-sized integral types (e.g., typically,int *andlong *). A warning is issued except inpccmode. Assignment of a string constant to a pointer to any kind of character is allowed without a warning.Assignment of pointer types is allowed in cases where the destination type has added type qualifiers that are not at the top level (e.g.,
int **toconst int **). Comparisons and pointer difference of such pairs of pointer types are also allowed. A warning is issued.In operations on pointers, a pointer to
voidis always implicitly converted to another type if necessary, and a null pointer constant is always implicitly converted to a null pointer of the right type if necessary. In ANSI C, some operators allow such things, and others (generally, where it does not make sense) do not allow them.Pointers to different function types may be assigned or compared for equality (
==) or inequality (!=) without an explicit type cast. A warning is issued. This extension is not allowed in C++ mode.A pointer to
voidmay be implicitly converted to or from a pointer to a function type.If the
ATT_PREPROCESSING_EXTENSIONS_ALLOWEDswitch isTRUE, the#assertpreprocessing extensions of AT&T System V release 4 are allowed. These allow definition and testing of predicate names. Such names are in a name space distinct from all other names, including macro names. A predicate name is given a definition by a preprocessing directive of the form#assertname#assertname (token-sequence)which defines the predicate name. In the first form, the predicate is not given a value. In the second form, it is given the value token-sequence.
Such a predicate can be tested in a
#ifexpression, as follows#name(token-sequence)which has the value
1if a#assertof that name with that token-sequence has appeared, and0otherwise. A given predicate may be given more than one value at a given time.A predicate may be deleted by a preprocessing directive of the form
#unassertname#unassertname(token-sequence)
The first form removes all definitions of the indicated predicate name; the second form removes just the indicated definition, leaving any others there may be.
GNU line directive flags are accepted on
#linedirectives. The system header flag is recognized, and the associated code is treated as if found in a system include directory.asmstatements and declarations are accepted. This is disabled in strict ANSI C mode (-Aor-aand-moptions) since it conflicts with the ANSI C standard for something likeasm("xyz");
which ANSI C interprets as a call of an implicitly-defined function
asmand which by default the front end interprets as anasmstatement.When
ASM_FUNCTION_ALLOWEDisTRUE, asm functions are accepted, and__asmis recognized as a synonym for asm. An asm function body is represented in the IL by an uninterpreted null-terminated string containing the text that appears in the source (including the text of source comments whenINCLUDE_COMMENTS_IN_ASM_FUNC_BODYisTRUE). An asm function must be declared with no storage class, with a prototyped parameter list, and with no omitted parameters:asm void f(int,int) { ... }
If asm functions are recognized and the C-generating back end is used, it is required that ANSI-C be generated, not K&R C, because the asm function must be put out with a prototyped parameter list.
If
ALLOW_NONSTANDARD_ANONYMOUS_UNIONSisTRUE, an extension is supported to allow constructs similar to C++ anonymous unions, including the following:not only anonymous unions but also anonymous structs are allowed — that is, their members are promoted to the scope of the containing struct and looked up like ordinary members;
they can be introduced into the containing struct by a
typedefname — they needn’t be declared directly, as with true anonymous unions; anda tag may be declared (C mode only).
Among the restrictions: the extension only applies to constructs within structs.
If
DEFAULT_ADDRESS_OF_ELLIPSIS_ALLOWEDisTRUE, the expression&...is accepted in the body of a function in which an ellipsis appears in the parameter list. It is needed to support some versions of macrova_startinstdarg.h.If
DEFAULT_ALLOW_ELLIPSIS_ONLY_PARAM_IN_C_MODEisTRUE, an ellipsis may appear by itself in the parameter list of a function declaration — e.g.,f(...). A diagnostic is issued in strict ANSI C mode.External entities declared in other scopes are visible. A warning is issued.
void f1(void) { extern void f(); } void f2() { f(); /* Using out of scope declaration */ }
A non-lvalue array expression is converted to a pointer to the first element of the array when it is subscripted or similarly used.
The nonstandard preprocessing directive
#include_nextis supported. This is a variant of the#includedirective. It searches for the named file only in the directories on the search path that follow the directory in which the current source file (the one containing the#include_nextdirective) is found. (This is an extension found in the GNU C compiler.)The nonstandard preprocessing directive
#warningis supported. It is similar to the#errordirective, but results in a warning instead of a catastrophic error when processed. This directive is not recognized in strict mode. (This is an extension found in GNU C compilers.)
In the following areas considered “undefined behavior” by the ANSI C standard, the front end does the following:
Adjacent wide and non-wide string literals are not concatenated unless
wchar_tandcharare the same type. (In C++ mode, whenwchar_tis a keyword, adjacent wide and non-wide string literals are never concatenated.)In character and string escapes, if the character following the
\has no special meaning, the value of the escape is the character itself. Thus"\s" == "s". A warning is issued.A
structthat has no named fields but at least one unnamed field is accepted by default, but a diagnostic (a warning or error) is issued in strict ANSI C mode.
Namespace Support¶
Namespaces are enabled by default
except in the cfront modes. The command-line options --namespaces and
--no_namespaces can be used to enable or disable the features.
When doing name lookup in a template instantiation, some names must be found in the context of the template definition while others may also be found in the context of the template instantiation. The front end implements two different instantiation lookup algorithms: the one mandated by the standard (referred to as “dependent name lookup”), and the one that existed before dependent name lookup was implemented.
Dependent name lookup is done in strict mode (unless explicitly disabled by another command-line option) or when dependent name processing is enabled by either a configuration flag or command-line option.
Dependent Name Processing¶
When doing dependent name lookup, the front end implements the
instantiation name lookup rules specified in the standard. This
processing requires that nonclass prototype instantiations be done. This
in turn requires that the code be written using the typename and
template keywords as required by the standard.
Lookup Using the Referencing Context¶
When not using dependent name lookup, the front end uses a name lookup algorithm that approximates the two-phase lookup rule of the standard, but does so in such a way that is more compatible with existing code and existing compilers.
When a name is looked up as part of a template instantiation but is not found in the local context of the instantiation, it is looked up in a synthesized instantiation context that includes both names from the context of the template definition and names from the context of the instantiation. Here’s an example:
namespace N {
int g(int);
int x = 0;
template <class T> struct A {
T f(T t) { return g(t); }
T f() { return x; }
};
}
namespace M {
int x = 99;
double g(double);
N::A<int> ai;
int i = ai.f(0); // N::A<int>::f(int) calls N::g(int)
int i2 = ai.f(); // N::A<int>::f() returns 0 (= N::x)
N::A<double> ad;
double d = ad.f(0); // N::A<double>::f(double) calls M::g(double)
double d2 = ad.f(); // N::A<double>::f() also returns 0 (= N::x)
}
The lookup of names in template instantiations does not conform to the rules in the standard in the following respects:
Although only names from the template definition context are considered for names that are not functions, the lookup is not limited to those names visible at the point at which the template was defined.
Functions from the context in which the template was referenced are considered for all function calls in the template. Functions from the referencing context should only be visible for “dependent” function calls.
For details of the algorithm implemented, see the Symbol Table chapter (in particular the section entitled “Instantiation Context Lookup”).
Argument Dependent Lookup¶
When argument-dependent lookup is enabled, functions made visible using
argument-dependent lookup overload with those made visible by normal
lookup. The standard requires that this overloading occur even when the
name found by normal lookup is a block extern declaration. The front end
does this overloading, but in default mode, argument-dependent lookup is
suppressed when the normal lookup finds a block extern.
This means a program can have different behavior, depending on whether it is compiled with or without argument-dependent lookup, even if the program makes no use of namespaces. For example:
struct A { };
A operator+(A, double);
void f() {
A a1;
A operator+(A, int);
a1 + 1.0; // calls operator+(A, double) with arg-dependent
} // lookup enabled but otherwise calls
// operator+(A, int);
Template Instantiation¶
The C++ language includes the concept of templates. A template is a
description of a class or function that is a model for a family of
related classes or functions. [2] For example, one can write a template
for a Stack class, and then use a stack of integers, a stack of floats,
and a stack of some user-defined type. In the source, these might be
written Stack<int>, Stack<float>, and Stack<X>. From a single source
description of the template for a stack, the compiler can create
instantiations of the template for each of the types required.
The instantiation of a class template is always done as soon as it is needed in a compilation. However, the instantiations of template functions, template variables, member functions of template classes, and static data members of template classes (hereafter referred to as template entities) are not necessarily done immediately, for several reasons:
One would like to end up with only one copy of each instantiated entity across all the object files that make up a program. (This of course applies to entities with external linkage.)
The language allows one to write a specialization of a template entity, i.e., a specific version to be used in place of a version generated from the template for a specific data type. (One could, for example, write a version of
Stack<int>, or of justStack<int>::push, that replaces the template-generated version; often, such a specialization provides a more efficient representation for a particular data type.) Since the compiler cannot know, when compiling a reference to a template entity, if a specialization for that entity will be provided in another compilation, it cannot do the instantiation automatically in any source file that references it. (The modern C++ language requires that a specialization be declared in every compilation in which it is used, but for compatibility with existing code and older compilers the EDG front end does not require that in some modes. See the command-line option--no_distinct_template_signatures.)C++ templates can be exported (i.e., declared with the keyword
export). Such templates can be used in a translation unit that does not contain the definition of the template to instantiate. The instantiation of such a template must be delayed until the template definition has been found.The language also dictates that template functions that are not referenced should not be compiled, that, in fact, such functions might contain semantic errors that would prevent them from being compiled. Therefore, a reference to a template class should not automatically instantiate all the member functions of that class.
(It should be noted that certain template entities are always instantiated when used, e.g., inline functions.)
From these requirements, one can see that if the compiler is responsible for doing all the instantiations automatically, it can only do so on a program-wide basis. That is, the compiler cannot make decisions about instantiation of template entities until it has seen all the source files that make up a complete program.
The EDG C++ front end provides an instantiation mechanism that does automatic instantiation at link time. For cases where the programmer wants more explicit control over instantiation, the front end also provides instantiation modes and instantiation pragmas, which can be used to exert fine-grained control over the instantiation process.
Automatic Instantiation¶
The goal of an automatic instantiation mode is to provide painless instantiation. The programmer should be able to compile source files to object code, then link them and run the resulting program, and never have to worry about how the necessary instantiations get done.
In practice, this is hard for a compiler to do, and different compilers use different automatic instantiation schemes with different strengths and weaknesses:
AT&T/USL/Novell/SCO’s cfront product saves information about each file it compiles in a special directory called
ptrepository. It instantiates nothing during normal compilations. At link time, it looks for entities that are referenced but not defined, and whose mangled names indicate that they are template entities. For each such entity, it consults theptrepositoryinformation to find the file containing the source for the entity, and it does a compilation of the source to generate an object file containing object code for that entity. This object code for instantiated objects is then combined with the “normal” object code in the link step.The programmer using cfront must follow a particular coding convention: all templates must be declared in
.hfiles, and for each such file there must be a corresponding.Cfile containing the associated definitions. The compiler is never told about the.Cfiles explicitly; one does not, for example, compile them in the normal way. The link step looks for them when and if it needs them, and does so by taking the.hfile name and replacing its suffix. [3]This scheme has the disadvantage that it does a separate compilation for each instantiated function (or, at best, one compilation for all the member functions of one class). Even though the function itself is often quite small, it must be compiled along with the declarations for the types on which the instantiation is based, and those declarations can easily run into many thousands of lines. For large systems, these compilations can take a very long time. The link step tries to be smart about recompiling instantiations only when necessary, but because it keeps no fine-grained dependency information, it is often forced to “recompile the world” for a minor change in a
.hfile. In addition, cfront has no way of ensuring that preprocessing symbols are set correctly when it does these instantiation compilations, if preprocessing symbols are set other than on the command line.Borland’s C++ compiler instantiates everything referenced in a compilation, then uses a special linker to remove duplicate definitions of instantiated functions.
The programmer using Borland’s compiler must make sure that every compilation sees all the source code it needs to instantiate all the template entities referenced in that compilation. That is, one cannot refer to a template entity in a source file if a definition for that entity is not included by that source file. In practice, this means that either all the definition code is put directly in the
.hfiles, or that each.hfile includes an associated.C(actually,.CPP) file.This scheme is straightforward, and works well for small programs. For large systems, however, it tends to produce very large object files, because each object file must contain object code (and symbolic debugging information) for each template entity it references.
EDG’s approach is a little different. It requires that, for each instantiation of a non-exported template, there is some (normal, top-level, explicitly-compiled) source file that contains the definition of the template entity, a reference that causes the instantiation, and the declarations of any types required for the instantiation. [4] This requirement can be met in various ways:
The Borland convention: each
.hfile that declares a template entity also contains either the definition of the entity or includes another file containing the definition.Implicit inclusion: when the compiler sees a template declaration in a
.hfile and discovers a need to instantiate that entity, it is given permission to go off looking for an associated definition file having the same base name and a different suffix, and it implicitly includes that file at the end of the compilation. This method allows most programs written using the cfront convention to be compiled with EDG’s approach. See the section on implicit inclusion.The ad hoc approach: the programmer makes sure that the files that define template entities also have the definitions of all the available types, and adds code or pragmas in those files to request instantiation of the entities there.
Exported templates are also supported by the EDG automatic instantiation method, but they require additional mechanisms explained further on.
The EDG automatic instantiation method works as follows for non-exported templates: [5]
The first time the source files of a program are compiled, no template entities are instantiated. However, template information files (with, by default, a
.tisuffix) are generated and contain information about things that could have been instantiated in each compilation [6].When the object files are linked together, a program called the prelinker is run. It examines the object files, looking for references and definitions of template entities, and for the added information about entities that could be instantiated.
If the prelinker finds a reference to a template entity for which there is no definition anywhere in the set of object files, it looks for a file that indicates that it could instantiate that template entity. When it finds such a file, it assigns the instantiation to it. The set of instantiations assigned to a given file is recorded in an associated instantiation request file (with, by default, a
.iisuffix).The prelinker then executes the compiler again to recompile each file for which the instantiation request file was changed. The original compilation command-line options (saved in the template information file) are used for the recompilation.
When the compiler compiles a file, it reads the instantiation request file for that file and obeys the requests therein. It produces a new object file containing the requested template entities (and all the other things that were already in the object file). The compiler also receives a definition list file, which lists all the instantiations for which definitions already exist in the set of object files. If during the compilation the compiler has the opportunity to instantiate a referenced entity that is not on that list, it goes ahead and does the instantiation. It passes back to the prelinker (in the definition list file) a list of the instantiations that it has “adopted” in this way, so the prelinker can assign them to the file. This adoption process allows rapid instantiation and assignment of instantiations referenced from new instantiations, and reduces the need to recompile a given file more than once during the prelinking process.
The prelinker repeats steps 3–5 until there are no more instantiations to be adjusted.
The object files are linked together.
Once the program has been linked correctly, the instantiation request files contain a complete set of instantiation assignments. From then on, whenever source files are recompiled, the compiler will consult the instantiation request files and do the indicated instantiations as it does the normal compilations. That means that, except in cases where the set of required instantiations changes, the prelink step from then on will find that all the necessary instantiations are present in the object files and no instantiation assignment adjustments need be done. That’s true even if the entire program is recompiled.
If the programmer provides a specialization of a template entity somewhere in the program, the specialization will be seen as a definition by the prelinker. Since that definition satisfies whatever references there might be to that entity, the prelinker will see no need to request an instantiation of the entity. If the programmer adds a specialization to a program that has previously been compiled, the prelinker will notice that too and remove the assignment of the instantiation from the proper instantiation request file.
The instantiation request files should not, in general, require any manual intervention. One exception: if a definition is changed in such a way that some instantiation no longer compiles (it gets errors), and at the same time a specialization is added in another file, and the first file is being recompiled before the specialization file and is getting errors, the instantiation request file for the file getting the errors must be deleted manually to allow the prelinker to regenerate it.
If the prelinker changes an instantiation assignment, it will issue a message like
C++ prelinker: A<int>::f() assigned to file test.o
C++ prelinker: executing: /edg/bin/eccp -c test.c
The automatic instantiation scheme can coexist with partial explicit control of instantiation by the programmer through the use of pragmas or command-line specification of the instantiation mode. See the following sections.
Instantiations are normally generated as part of the object file of the translation unit in which the instantiations are performed. But when “one instantiation per object” mode is specified, each instantiation is placed in its own object file. One-instantiation-per-object mode is useful when generating libraries that need to include copies of the instances referenced from the library. If each instance is not placed in its own object file, it may be impossible to link the library with another library containing some of the same instances. Without this feature it is necessary to create each individual instantiation object file using the manual instantiation mechanism.
The automatic instantiation mode can be configured out altogether by
setting the configuration flag AUTOMATIC_TEMPLATE_INSTANTIATION to
FALSE. It can be turned on or off using the --auto_instantiation and
‑‑no_auto_instantiation command-line options. If automatic instantiation
is turned off, the template information file is not generated.
Instantiation Modes¶
Normally, when a file is compiled, no template entities are instantiated (except those assigned to the file by automatic instantiation). The overall instantiation mode can, however, be changed by a command line option:
|
Do not automatically create instantiations of any template entities. This is the default. It is also the usually appropriate mode when automatic instantiation is done. |
|
Instantiate those template entities that were used in the compilation. This will include all static data members for which there are template definitions. |
|
Instantiate all template entities declared or referenced in the compilation unit. For each fully instantiated template class, all of its member functions and static data members will be instantiated whether or not they were used. Nonmember template functions will be instantiated even if the only reference was a declaration. |
|
Similar to |
In the case where the eccp script is given a single file to compile and
link, e.g.,
eccp t.c
the compiler knows that all instantiations will have to be done in the
single source file. Therefore, it uses the -tused mode and suppresses
automatic instantiation.
Instantiation #pragma Directives¶
Instantiation pragmas can be used to control the instantiation of specific template entities or sets of template entities. There are three instantiation pragmas:
The
instantiatepragma causes a specified entity to be instantiated.The
do_not_instantiatepragma suppresses the instantiation of a specified entity. It is typically used to suppress the instantiation of an entity for which a specific definition will be supplied.The
can_instantiatepragma indicates that a specified entity can be instantiated in the current compilation, but need not be; it is used in conjunction with automatic instantiation, to indicate potential sites for instantiation if the template entity turns out to be required. [7]
The argument to the instantiation pragma may be:
a template class name
A<int>a template class declaration
class A<int>a member function name
A<int>::fa static data member name
A<int>::ia static data member decl.
int A<int>::ia member function declaration
void A<int>::f(int, char)a template function declaration
char* f(int, float)a template variable name
x<int>
A pragma in which the argument is a template class name (e.g., A<int> or
class A<int>) is equivalent to repeating the pragma for each member
function and static data member declared in the class. When
instantiating an entire class a given member function or static data
member may be excluded using the do_not_instantiate pragma. For example,
#pragma instantiate A<int>
#pragma do_not_instantiate A<int>::f
The template definition of a template entity must be present in the
compilation for an instantiation to occur. If an instantiation is
explicitly requested by use of the instantiate pragma and no template
definition is available or a specific definition is provided, an error
is issued.
template <class T> void f1(T); // No body provided
template <class T> void g1(T); // No body provided
void f1(int) {} // Specific definition
void main()
{
int i;
double d;
f1(i);
f1(d);
g1(i);
g1(d);
}
#pragma instantiate void f1(int) // error - specific definition
#pragma instantiate void g1(int) // error - no body provided
f1(double) and g1(double) will not be instantiated (because no bodies
were supplied) but no errors will be produced during the compilation (if
no bodies are supplied at link time, a linker error will be produced).
A member function name (e.g., A<int>::f) can only be used as a pragma
argument if it refers to a single user defined member function (i.e.,
not an overloaded function). Compiler-generated functions are not
considered, so a name may refer to a user defined constructor even if a
compiler-generated copy constructor of the same name exists. Overloaded
member functions can be instantiated by providing the complete member
function declaration, as in
#pragma instantiate char* A<int>::f(int, char*)
The argument to an instantiation pragma may not be a compiler-generated function, an inline function, or a pure virtual function.
Implicit Inclusion¶
When implicit inclusion is enabled, the front end is given permission to
assume that if it needs a definition to instantiate a template entity
declared in a .h file it can implicitly include the corresponding .C
file to get the source code for the definition. For example, if a
template entity ABC::f is declared in file xyz.h, and an instantiation
of ABC::f is required in a compilation but no definition of ABC::f
appears in the source code processed by the compilation, the compiler
will look to see if a file xyz.C exists, and if so it will process it as
if it were included at the end of the main source file.
To find the template definition file for a given template entity the
front end needs to know the path name specified in the original include
of the file in which the template was declared and whether the file was
included using the system include syntax (e.g., #include <file.h>). This
information is not available for preprocessed source containing #line
directives. Consequently, the front end will not attempt implicit
inclusion for source code containing #line directives.
The file to be implicitly included is found by replacing the file suffix with each of the suffixes specified in the instantiation file suffix list. The normal include search path mechanism is then used to look for the file to be implicitly included.
DEFAULT_INSTANTIATION_FILE_SUFFIX_LIST defines the set of
definition-file suffixes tried. By default, the list is .c, .C,
.cpp, .CPP, .cxx, .CXX, and .cc.
Implicit inclusion works well alongside automatic instantiation, but the two are independent. They can be enabled or disabled independently, and implicit inclusion is still useful when automatic instantiation is not done.
The implicit inclusion mode can be configured out altogether by setting
the configuration flag INSTANTIATION_BY_IMPLICIT_INCLUSION to FALSE. It
can be turned on or off using the --implicit_include and
‑‑no_implicit_include command-line options.
Implicit inclusions are only performed during the normal compilation of
a file, (i.e., not when doing only preprocessing). A common means of
investigating certain kinds of problems is to produce a preprocessed
source file that can be inspected. When using implicit inclusion it is
sometimes desirable for the preprocessed source file to include any
implicitly included files. This may be done using the --no_preproc_only
command line option. This causes the preprocessed output to be generated
as part of a normal compilation. When implicit inclusion is being used,
the implicitly included files will appear as part of the preprocessed
output in the precise location at which they were included in the
compilation.
Extern Inline Functions¶
Depending on the way in which the front end is configured, out-of-line copies of extern inline functions are either implemented using static functions, or are instantiated using a mechanism like the template instantiation mechanism. Note that out-of-line copies of inline functions are only required in cases where the function cannot be inlined, or when the address of the function is taken (whether explicitly by the user, by implicitly generated functions, or by compiler-generated data structures such as virtual function tables or exception handling tables).
When static functions are used, local static variables of the functions are promoted to global variables with specially encoded names, so that even though there may be multiple copies of the code, there is only one copy of such global variables. This mechanism does not strictly conform to the standard because the address of an extern inline function is not constant across translation units.
When the instantiation mechanism is used, the address of an extern
inline function is constant across translation units, but at the cost of
requiring the use of one of the template instantiation mechanisms, even
for programs that don’t use templates. Definitions of extern inline
functions can be provided either through use of the automatic
instantiation mechanism or by use of the -tused or -tall instantiation
modes. There is no mechanism to manually control the definition of
extern inline function bodies.
Predefined Macros¶
The front end defines a number of preprocessing macros. Many of them are only defined under certain circumstances. This section describes the macros that are provided and the circumstances under which they are defined. In addition, a table of predefined macro definitions may be processed when the compiler is invoked. This may be used for any kind of predefined macro, but in particular is used to define the macros that gcc and g++ define when using gcc and g++ modes. The format of the file and other information is described in section sec:reference_guide:cafe:configuration.
|
Defined in ANSI C mode and in C++ mode. In C++ mode the value may be redefined. Not defined in Microsoft compatibility mode. |
|
Defined in all modes to the date of the compilation in the form “Mmm dd yyyy”. |
|
Defined in all modes to the time of the compilation in the form “hh:mm:ss”. |
|
Defined in all modes to the name of the current source file. |
|
Defined in all modes to the current source line number within the current source file. |
|
Defined in C++ modes. In general, the value is |
|
Defined in cfront mode. |
|
Defined in C++/CLI mode with the value |
|
Defined in ANSI C mode with the value |
|
Defined in C99 and C++11 modes with the value
specified by the |
|
Defined in C99 mode if the configuration macro
|
|
Defined in C99 mode if the configuration macro |
|
Defined in C99 mode if the configuration macro
|
|
Defined in C99 mode if the configuration macro |
|
Defined when plain |
|
Defined in all modes to the name of the current function. An error is issued if it is used outside of a function. An EDG, GNU, and Microsoft extension. (Depending on the current mode, this identifier behaves as a variable or as a string literal; never as a preprocessor macro.) |
|
Same as |
|
Defined in all modes to the name of the current function. This includes the return type and parameter types of the function. An error is issued if it is used outside of a function. An EDG and GNU extension. (Depending on the current mode, this identifier behaves as a variable or as a string literal; never as a preprocessor macro.) |
|
Same as |
|
Defined to the “decorated” name of the current function (i.e., its mangled name) in Microsoft mode. (This identifier behaves as a string literal; not as a preprocessor macro.) |
|
Defined in all modes. Similar to |
|
Defined in C++ mode when |
|
Defined in Microsoft C++ mode when |
|
Defined in Microsoft C++ mode when |
|
Defined in C++ mode when |
|
Defined in Microsoft C++ mode when |
|
Defined in C++ mode when array new and delete are
enabled. The name of this macro and whether it is predefined are
specified by configuration options. |
|
Defined in C++ mode when exception handling is enabled.
The name of this macro and whether it is predefined are specified by
configuration options. |
|
Defined in C++ mode when RTTI is enabled. The name of this macro
and whether it is predefined are specified by configuration options.
|
|
Defined in C++ mode when placement delete is
enabled. The name of this macro and whether it is predefined are
specified by configuration options. |
|
Defined in all modes when the |
|
Defined in C++ mode when the configuration flag |
|
Defined in C++ mode when the configuration flag |
|
Defined in non-Microsoft modes when type traits pseudo-functions (to
ease the implementation of ISO/IEC TR 19768; e.g., |
|
Always defined. |
|
Defined to an integral value that represents the version number of the front end. For example. version 2.30 is represented as 230. |
|
Defined as 1 when using a front end configured to use the IA-64 ABI. |
|
Defined as 1 in Embedded C++ mode. |
|
Defined in Microsoft mode when |
|
Defined in Microsoft mode to the version number of the Microsoft compiler that is to be emulated. For example, 1100 is the value that corresponds to Visual C++ version 5.0. |
|
Defined in Microsoft mode to the value of |
|
Defined in Microsoft mode when C++/CLI mode is in effect (e.g.,
when |
|
Defined in Microsoft mode. |
|
Defined (unconditionally) in Microsoft mode. |
|
Defined in Microsoft mode when |
|
Defined in Microsoft mode to the number of bits in the largest integral type that is supported. The value depends on the way in which the front end was configured. |
|
Defined in Microsoft mode C++ when RTTI is enabled. |
|
Defined in GNU mode to the value specified by the |
|
Defined in GNU mode to the value specified by the
|
|
Defined in GNU mode to the value specified by the
|
|
Defined if all modes when the configuration flag
|
|
Defined when UPC extensions are enabled. |
|
Defined in Microsoft mode. Returns an integer value, starting with zero and incremented each time the macro is used. |
|
Defined in Microsoft mode. Returns a string literal containing the modification date and time of the source file in which it is specified. |
|
Defined in C++ mode when using the IA-64 ABI. The name
of this predefined macro is specified by a configuration option.
|
|
Defined in C++ mode when using the IA-64 ABI when guard variables are
int-sized (i.e., in the ARM EABI). The name of this predefined macro is
specified by a configuration option.
|
|
Defined in C++ mode when using the IA-64 ABI when constructors and
destructors return the this pointer (i.e., in the ARM EABI). The name of
this predefined macro is specified by a configuration option.
|
|
Defined to be the type of |
|
Defined to be the type of |
|
Defined in C++ mode when |
|
Defined in GNU mode as the underlying type for
|
|
Defined in GNU mode as the underlying type for
|
|
Defined in C++ mode when variadic templates are supported. The name of
this macro and whether it is predefined are specified by configuration
options. |
|
Defined in C++ mode when the implementation
supports multiple threads (i.e., when
|
Pragmas¶
#pragma directives are used within the source program to request certain
kinds of special processing. The #pragma directive is part of the
standard C and C++ languages, but the meaning of any pragma is
implementation-defined.
Instantiation Pragmas¶
The following are described in detail in the template instantiation section of this chapter:
#pragma instantiate
#pragma do_not_instantiate
#pragma can_instantiate
Precompiled Header Pragmas¶
The following are described in the section on precompiled header processing:
#pragma hdrstop
#pragma no_pch
Once Pragma¶
The front end also recognizes #pragma once, which, when placed at the
beginning of a header file, indicates that the file is written in such a
way that including it several times has the same effect as including it
once. Thus, if the front end sees #pragma once at the start of a header
file, it will skip over it if the file is #included again.
A typical idiom is to place an #ifndef guard around the body of the
file, with a #define of the guard variable after the #ifndef:
#pragma once // optional
#ifndef FILE_H
#define FILE_H
... body of the header file ...
#endif
The #pragma once is marked as optional in this example, because the
front end recognizes the #ifndef idiom and does the optimization even in
its absence. #pragma once is accepted for compatibility with other
compilers and to allow the programmer to use other guard-code idioms.
Diagnostic Pragmas¶
The following pragmas may be used to control the error severity used when a given diagnostic message is issued.
#pragma diag_suppress
#pragma diag_remark
#pragma diag_warning
#pragma diag_error
#pragma diag_default
#pragma diag_once
These are similar in function to the equivalent command-line options. Uses of these pragmas have the following form:
#pragma diag_xxx [=] error_number_or_tag, error_number_or_tag ...
The diagnostic affected is specified using either an error number or an
error tag name. The = is optional. Any diagnostic may be overridden to
be an error, but only diagnostics with a severity of discretionary error
or below may have their severity reduced to a warning or below, or be
suppressed. The diag_default pragma is used to return the severity of a
diagnostic to the one that was in effect before any pragmas were issued
(i.e., the normal severity of the message as modified by any
command-line options). The following example suppresses the “pointless
friend declaration” warning on the declaration of class A:
#pragma diag_suppress 522
class A { friend class A; };
#pragma diag_default 522
class B { friend class B; };
The diag_once pragma causes the specified diagnostics to be issued only
once as a warning or remark.
Pack Pragma¶
When USER_CONTROL_OF_STRUCT_PACKING is TRUE, #pragma pack is recognized.
It is used to specify the maximum alignment allowed for nonstatic data
members of structs and classes, even if that alignment is less than the
alignment dictated by the member’s type.
The basic syntax is:
#pragma pack(n)#pragma pack()
where argument n, a power-of-2 value within the range defined by
TARG_MINIMUM_PACK_ALIGNMENT and TARG_MAXIMUM_PACK_ALIGNMENT, is the new
packing alignment that is to go into effect for subsequent declarations,
until another #pragma pack is seen. The second form cancels the effect
of a preceding #pragma pack(n) and either restores the default
packing alignment specified by the --pack_alignment command-line option
or, if the option was not used, disables the packing of structs and
classes.
An enhanced syntax (intended to be compatible with the similar facility offered by Microsoft C/C++ compilers) is also supported in which keywords push and pop can be used to manage a stack of packing alignment values — for instance:
#pragma pack (push, xxx, 16)
/* Packing alignment set to 16. */
#include "xxx.h"
#pragma pack (pop, xxx)
/* Packing alignment reset to what it was prior to the
above #pragma pack directive, even if the included header
left some unrelated pragma pack entries on the stack. */
which has the effect saving the current packing alignment value and establishing a new one, processing the include file (which may leave the packing alignment with an unknown setting), and restoring the original value. Finally, the form
#pragma pack(show)
causes the front end to emit a warning describing the current setting of the maximum member alignment (if any).
In C++ a #pragma pack directive has “local” effect when it appears
inside a function template, an instantiation of a class template, or the
body of a member function or friend function that is defined within a
class definition. When such a context is entered, the current pack
alignment state is saved, so that it can be restored when the context is
exited. For example,
template <class T> class A {
:
#pragma pack(1)
:
};
#pragma pack(4)
main() {
A<int> a; // #pragma pack(1) is local to A<int>
struct S { char c; int i; }; // sizeof(S) == 8, not 5
}
Moreover, within an instantiation of a class or function template, the default pack alignment is that which is in effect at the point of the template’s definition, not at the point of its instantiation. Here is an example:
#pragma pack(1)
template <class T> int f(T) {
struct S { char c; int i; }; // default pack alignment is 1 for each
return sizeof(S); // instance of f<T>
}
#pragma pack(4)
main() {
int i = f(0); // i = 5, not 8
}
These rules apply to inline-defined member functions, too, because their bodies are also scanned “out of order” relative to the textual order of the source program (i.e., not till all the class members have been declared).
#pragma pack(4)
struct A {
int f() {
#pragma pack(1) // #pragma pack(1) is local to A::f
struct S { char c; int i; }; // sizeof(S) is 5
}
int g() {
struct S { char c; int i; }; // sizeof(S) is 8
}
#pragma pack(1)
int h() {
struct S { char c; int i; }; // sizeof(S) is 5
}
};
When IDENT_DIRECTIVE_AND_PRAGMA is TRUE, #pragma ident is recognized, as
is #ident:
#pragma ident“string”#ident“string”
Both are implemented by recording the string in a pragma entry and passing it to the back end.
When PRAGMA_WEAK_ALLOWED is TRUE, #pragma weak is recognized.
Its form is
#pragma weakname1 [ = name2 ]
where name1 is the name to be given “weak binding” and is a synonym for name2 if the latter is specified. The entire argument string is recorded in the pragma entry and passed to the back end.
Microsoft Pragmas¶
The following pragmas are accepted in Microsoft mode:
#pragma push_macro(“identifier”)
#pragma pop_macro(“identifier”)
#pragma include_alias(“a_long_file_name.h”, “short.h”)
In addition, when NATIVE_MULTIBYTE_CHARS_SUPPORTED_WITH_UNICODE is TRUE, the setlocale pragma is accepted:
#pragma setlocale("locale name")
The pack pragma is also accepted by the Microsoft compiler, but its
acceptance by the front end is controlled by a separate configuration
flag, not by whether or not Microsoft mode is being used.
Precompiled Headers¶
It is often desirable to avoid recompiling a set of header files,
especially when they introduce many lines of code and the primary source
files that #include them are relatively small. The EDG front end
provides a mechanism for, in effect, taking a snapshot of the state of
the compilation at a particular point and writing it to a disk file
before completing the compilation; then, when recompiling the same
source file or compiling another file with the same set of header files,
it can recognize the “snapshot point,” verify that the corresponding
precompiled header (“PCH”) file is reusable, and read it back in. Under
the right circumstances, this can produce a dramatic improvement in
compilation time; the trade-off is that PCH files can take a lot of disk
space.
Automatic Precompiled Header Processing¶
When --pch appears on the command line, automatic precompiled header
processing is enabled. This means the front end will automatically look
for a qualifying precompiled header file to read in and/or will create
one for use on a subsequent compilation.
The PCH file will contain a snapshot of all the code preceding the
“header stop” point. The header stop point is typically the first token
in the primary source file that does not belong to a preprocessing
directive, but it can also be specified directly by #pragma hdrstop (see
below) if that comes first. For example:
#include "xxx.h"
#include "yyy.h"
int i;
The header stop point is int (the first non-preprocessor token) and the
PCH file will contain a snapshot reflecting the inclusion of xxx.h and
yyy.h. If the first non-preprocessor token or the #pragma hdrstop
appears within a #if block, the header stop point is the outermost
enclosing #if. To illustrate, here’s a more complicated example:
#include "xxx.h"
#ifndef YYY_H
#define YYY_H 1
#include "yyy.h"
#endif
#if TEST
int i;
#endif
Here, the first token that does not belong to a preprocessing directive
is again int, but the header stop point is the start of the #if block
containing it. The PCH file will reflect the inclusion of xxx.h and
conditionally the definition of YYY_H and inclusion of yyy.h; it will
not contain the state produced by #if TEST.
A PCH file will be produced only if the header stop point and the code preceding it (mainly, the header files themselves) meet certain requirements:
The header stop point must appear at file scope — it may not be within an unclosed scope established by a header file. For example, a PCH file will not be created in this case:
// xxx.h class A { // xxx.C #include "xxx.h" int i; };
The header stop point may not be inside a declaration started within a header file, nor (in C++) may it be part of a declaration list of a linkage specification. For example, in the following case the header stop point is
int, but since it is not the start of a new declaration, no PCH file will be created:// yyy.h static // yyy.C #include "yyy.h" int i;
Similarly, the header stop point may not be inside a
#ifblock or a#definestarted within a header file.The processing preceding the header stop must not have produced any errors. (Note: warnings and other diagnostics will not be reproduced when the PCH file is reused.)
No references to predefined macros
__DATE__or__TIME__may have appeared.No use of the
#linepreprocessing directive may have appeared.#pragma no_pch(see below) must not have appeared.The code preceding the header stop point must have introduced a sufficient number of declarations to justify the overhead associated with precompiled headers.
When a precompiled header file is produced, it contains, in addition to the snapshot of the compiler state, some information that can be checked to determine under what circumstances it can be reused. This includes:
The compiler version, including the date and time the compiler was built.
The current directory (i.e., the directory in which the compilation is occurring).
The command line options.
The initial sequence of preprocessing directives from the primary source file, including
#includedirectives.The date and time of the header files specified in
#includedirectives.
This information comprises the PCH “prefix.” The prefix information of a given source file can be compared to the prefix information of a PCH file to determine whether the latter is applicable to the current compilation.
As an illustration, consider two source files:
// a.C
#include "xxx.h"
... // Start of code
// b.C
#include "xxx.h"
... // Start of code
When a.C is compiled with --pch, a precompiled header file named a.pch
is created. Then, when b.C is compiled (or when a.C is recompiled), the
prefix section of a.pch is read in for comparison with the current
source file. If the command line options are identical, if xxx.h has not
been modified, and so forth, then, instead of opening xxx.h and
processing it line by line, the front end reads in the rest of a.pch and
thereby establishes the state for the rest of the compilation.
It may be that more than one PCH file is applicable to a given compilation. If so, the largest (i.e., the one representing the most preprocessing directives from the primary source file) is used. For instance, consider a primary source file that begins with
#include "xxx.h"
#include "yyy.h"
#include "zzz.h"
If there is one PCH file for xxx.h and a second for xxx.h and yyy.h,
the latter will be selected (assuming both are applicable to the current
compilation). Moreover, after the PCH file for the first two headers is
read in and the third is compiled, a new PCH file for all three headers
may be created.
When a precompiled header file is created, it takes the name of the
primary source file, with the suffix replaced by an
implementation-specified suffix (see PCH_FILE_SUFFIX, which is set to
pch by default). Unless --pch_dir is specified (see below), it is
created in the directory of the primary source file.
When a precompiled header file is created or used, a message such as
"test.C": creating precompiled header file "test.pch"
is issued. The user may suppress the message by using the command-line
option --no_pch_messages.
When the --pch_verbose option is used the front end will display a
message for each precompiled header file that is considered that cannot
be used giving the reason that it cannot be used.
In automatic mode (i.e., when --pch is used) the front end will deem a
precompiled header file obsolete and delete it under the following
circumstances:
if the precompiled header file is based on at least one out-of-date header file but is otherwise applicable for the current compilation; or
if the precompiled header file has the same base name as the source file being compiled (e.g.,
xxx.pchandxxx.C) but is not applicable for the current compilation (e.g., because of different command-line options).
This handles some common cases; other PCH file clean-up must be dealt with by other means (e.g., by the user).
Support for precompiled header processing is not available when multiple source files are specified in a single compilation: an error will be issued and the compilation aborted if the command line includes a request for precompiled header processing and specifies more than one primary source file.
Manual Precompiled Header Processing¶
Command-line option --create_pch file-name specifies that a
precompiled header file of the specified name should be created.
Command-line option --use_pch file-name specifies that the indicated
precompiled header file should be used for this compilation; if it is
invalid (i.e., if its prefix does not match the prefix for the current
primary source file), a warning will be issued and the PCH file will not
be used.
When either of these options is used in conjunction with --pch_dir, the
indicated file name (which may be a path name) is tacked on to the
directory name, unless the file name is an absolute path name.
The --create_pch, --use_pch, and --pch options may not be used together.
If more than one of these options is specified, only the last one will
apply. Nevertheless, most of the description of automatic PCH processing
applies to one or the other of these modes — header stop points are
determined the same way, PCH file applicability is determined the same
way, and so forth.
Other Ways for Users to Control Precompiled Headers¶
There are several ways in which the user can control and/or tune how precompiled headers are created and used.
#pragma hdrstopmay be inserted in the primary source file at a point prior to the first token that does not belong to a preprocessing directive. It enables the user to specify where the set of header files subject to precompilation ends. For example,#include "xxx.h" #include "yyy.h" #pragma hdrstop #include "zzz.h"
Here, the precompiled header file will include processing state for
xxx.handyyy.hbut notzzz.h. (This is useful if the user decides that the information added by what follows the#pragma hdrstopdoes not justify the creation of another PCH file.)Command-line option
--pch_header_stopheader-name can be used to place add a header stop at the end of the named header, as if#pragma hdrstopwas placed immediately after the include of that header.#pragma no_pchmay be used to suppress precompiled header processing for a given source file.Command-line option
--pch_dirdirectory-name is used to specify the directory in which to search for and/or create a PCH file.
Performance Issues¶
The relative overhead incurred in writing out and reading back in a precompiled header file is quite small for reasonably large header files.
In general, it doesn’t cost much to write a precompiled header file out even if it does not end up being used, and if it is used it almost always produces a significant speedup in compilation. The problem is that the precompiled header files can be quite large (up to several gigabytes or more), and so one probably doesn’t want many of them sitting around.
Thus, despite the faster recompilations, precompiled header processing is not likely to be justified for an arbitrary set of files with nonuniform initial sequences of preprocessing directives. Rather, the greatest benefit occurs when a number of source files can share the same PCH file. The more sharing, the less disk space is consumed. With sharing, the disadvantage of large precompiled header files can be minimized, without giving up the advantage of a significant speedup in compilation times.
Consequently, to take full advantage of header file precompilation,
users should expect to reorder the #include sections of their source
files and/or to group #include directives within a commonly used header
file.
The EDG front end source provides an example of how this can be done. A common idiom is this:
#include "fe_common.h"
#pragma hdrstop
#include ...
where fe_common.h pulls in, directly and indirectly, a few dozen header
files; the #pragma hdrstop is inserted to get better sharing with fewer
PCH files. The PCH file produced for fe_common.h is a bit over a
megabyte in size. Another idiom, used by the source files involved in
declaration processing, is this:
#include "fe_common.h"
#include "decl_hdrs.h"
#pragma hdrstop
#include ...
decl_hdrs.h pulls in another dozen header files, and a second, somewhat
larger, PCH file is created. In all, the fifty-odd source files of the
EDG front end share just six precompiled header files. If disk space
were at a premium, one could decide to make fe_common.h pull in all
the header files used — then, a single PCH file could be used in
building the EDG front end.
Different environments and different projects will have different needs, but in general, users should be aware that making the best use of the precompiled header support will require some experimentation and probably some minor changes to source code.
1. However, if STACK_REFERENCED_INCLUDE_DIRECTORIES is TRUE, the
directories of all the source input files currently in use are
searched, in reverse order of #include nesting
1. Since templates are descriptions of entities (typically, classes) that are parameterizable according to the types they operate upon, they are sometimes called parameterized type
1. The actual implementation allows for several different suffixes and provides a command-line option to change the suffixes sough
1. Isn’t this always the case? No. Suppose that file A contains a
definition of class X and a reference to Stack<X>::push, and that
file B contains the definition for the member function push. There
would be no file containing both the definition of push and the
definition of
2. It should be noted that automatic instantiation, more than most aspects of the C++ language, requires environmental support outside of the compiler. This is likely to be operating-system and object-format dependent. The front end is delivered with an implementation that works under certain UNIX systems, and that involves code in the front end proper, in IL lowering, in a separate prelinker program, and in the eccp driver script. Because the environmental issues vary so much from system to system, this code should be viewed as a sample implementation that may need adaptation to work on other system
3. As a configuration option, and in older versions of the front end, the information about entities that could be instantiated, etc. can be represented in the names of generated variables added to the object program. For example, a name __CBI__mangled-name indicates that the entity with the given mangled name could be instantiated, but wasn’t. This alternate scheme has the advantage that the object file and the associated instantiation flags can never be out of sync. It has the disadvantage that the object files produced can be quite a bit larger because of the name strings for these generated external variable
1. At the moment, the can_instantiate pragma ends up forcing the instantiation of the template instance even if it isn’t referenced somewhere else in the program; that’s a weakness of the initial implementation which we expect to address
This is the end of documentation taken from the underlying EDG C/C++ parsing front end and is reprinted with permission. Copyright belongs to Edison Design Group, Inc.
Ignore Tokens¶
The following special tokens can be used when switch --ignore_tokens is
specified to ignore (e. g. via macro definitions) unwanted tokens in the source code.
- __ignore_next_token
The token after this token is skipped.
- __ignore_till_semicolon
All tokens until the next semicolon are skipped.
- __ignore_next_brackets
The next matching pair of brackets (braces, parentheses, etc.) including their content are skipped.
- __ignore_next_brackets_or_till_semicolon
Behaves like __ignore_next_brackets except if a semicolon appears before the first opening bracket, in which case it behaves like __ignore_till_semicolon.
- __ignore_init
An initialization following this token is skipped.
In order to correctly parse the following code, you can call cafeCC with the
options --ignore_tokens -Dinterrupt=__ignore_next_brackets:
interrupt [42] void my_irq42_handler(void)
{
}
Interrupts and entry points¶
The frontend cafe understands different attributes depending on the language
mode:
Language mode |
Attribute syntax |
|---|---|
GNU |
|
Microsoft |
|
C++11 |
|
C (with –gnu_attributes) |
|
Where name is an attribute name.
This can be used to mark entry points (e. g. interrupt handlers) like in the following
examples by using attribute name interrupt (or, equivalently,
interrupt_handler). In GNU mode one would write:
#ifdef __AXIVION__
#define INTERRUPT __attribute__((interrupt))
#else
#define INTERRUPT __interrupt__
#endif
INTERRUPT void timer_handler(void)
{
// handle timer tick here ...
}
Or in C++11 mode:
#ifdef __AXIVION__
#define INTERRUPT [[interrupt]]
#else
#define INTERRUPT __interrupt__
#endif
INTERRUPT void timer_handler(void)
{
// handle timer tick here ...
}
Entry points can be configured via rules EntryPoints-EntriesByName or
EntryPoints-EntriesByMacro.
For example, if you configure TASK as EntryPoints-EntriesByMacro/macros,
then a function definition using macro TASK is considered an entry point,
like the following:
#define TASK(x) void x(void)
TASK(my_handler)
{
}
Axivion specific pragmas¶
cafe recognizes one special pragma to modify the behavior while preprocessing:
- immutable_macro
The token following is considered a macro name. The state of this macro at the pragma location is considered immutable so that no future
#defineor#undefcan change it.
You can use this pragma from within a preinclude file in order to protect macros from being overwritten later on.
/* Do an analysis of the DEBUG build but without expanded assert() macros. */
#define assert(expr)
#pragma immutable_macro assert
/* Define a specific version and protect it from redefinition in headers. */
#define TOOL_VERSION 42
#pragma immutable_macro TOOL_VERSION
/* Protect automatic enabling of unwanted features in headers. */
#undef BOOST_NO_EXCEPTIONS
#pragma immutable_macro BOOST_NO_EXCEPTIONS
Additionally, the EDG pragmas diag_suppress, diag_remark,
diag_warning, diag_error, diag_once, and diag_default
(as well as their command-line counterparts) have been modified to accept * as
argument with the meaning “all diagnostics”.
6.4.1.4. irlink¶
irlink is the linker for IR files. It performs global name resolution on IR
unit files and generates a globally linked IR system file which describes the whole
system. irlink can combine IR files for C and for C++, but usually you needn’t
worry about those things as cafeCC already takes care of that.
Caution
Under normal circumstances, it is preferable to call cafeCC instead of
irlink
Command-Line Switches¶
irlink [options] <input file(s)> <output file>
Option |
Meaning |
|---|---|
|
Link library (no need for a main function). |
|
Link static part of binary, will be linked against runtime libs later. |
|
Keep going even if input files are missing. |
|
Link incrementally using groups of <n> object files. [2 – 2000] (default: 500) |
|
Link incrementally using groups of <n> library/archive files. [2 – 2000] (default: 20) |
|
Allow combinations of object files and libraries/archives in partitions for incremental linking (partition size via -i). |
|
Link groups separately (in parallel when -j is used) as first step, then combine them in next level. |
|
Link in all members of archives, not just those referenced from files appearing earlier on the command-line. |
|
Consider all archives mentioned consecutively as a single group. |
|
Consider members of following archives as required. |
|
Stops effect of –whole_archive, members of following archives are not automatically required. |
|
Consider following archives (until –end_group) as a single group. |
|
Sets end of archive group started with –start_group. |
|
Force separation of static symbols/unnamed namespaces of same unit. |
|
Tolerate mixed use of wchar_t as keyword and as typedef. |
|
Show more messages about differences. |
|
Make the given symbol(s) local to the result. This information is read from the given file. |
|
Suppress all warnings. |
|
Suppress all messages regarding code differences. |
|
Do not save linker messages in result IR file. |
|
Do not print the number of build messages. |
|
Emulate dlopen/LoadLibrary by statically linking in libraries. |
|
Link multiple binaries together to analyze a complete system. |
|
Print linking plan. |
|
Check for unused libraries. |
|
When checking for unused libraries, print symbol bindings into given file. |
|
Map path prefix of stored library references. |
|
Use <n> threads for linking in parallel where possible. Use the Default Parallelism logic if <n> is omitted. [1 - 4096] (default: 1) |
|
Keep log file even after successful termination. |
|
Also write all enabled messages into the log file. |
|
Suppress messages for files matching the given pattern(s). |
|
Tag result as summary information for external functions. |
|
Use only first occurrence of an input file if listed more than once. |
The input files have to be IR unit files, IR system files, or
ar archives. The output file is a linked system IR file.
IR archives are files generated with ar that contain IR files. irlink
understands files created with ar. On Windows® we supply the tool cafeAR
to build static archives in case no ar is available.
If non-IR files are listed as input files, irlink warns about them but otherwise
continues as if they had not been specified.
Parallel linking (with -j) in standard mode only does limited
parallelization; to achieve higher parallelization, combine -j with
--separate_groups. Notice that archives as input files cannot be split
between subprocesses, so linking of archives cannot benefit much from parallelization.
Also notice that multiple irlink subprocesses of course require more memory. Depending
on available memory and the speed of your hard disk and CPU, increasing the values of
options -I and -i might outperform parallelization.
6.4.1.5. build_cbp¶
build_cbp reads Code::Blocks project files for C/C++ projects (*.cbp)
and issues the necessary calls to cafeCC.
Note
build_cbp internally calls cafeCC. Therefore all configuration
issues that are relevant for cafeCC apply here as well. Similarly, for the
calls to the back-end cafe, the respective configuration is used. Please
refer to the Configuration sections of these tools for more information.
Command-Line Switches¶
usage: build_cbp [-h] [--clean] [-B basepath] [-j [N]] [-n] [-r]
[--incremental INCREMENTAL] [--single_file filename]
[--carg argument] [--larg argument] [--target targetname]
project.cbp
|
The project to analyze. |
|
Cleans project (instead of building). |
|
Set source base path (only set if you understand the implications). |
|
Execute with N processes in parallel. N=1 if switch omitted, use the Default Parallelism logic if N omitted. |
|
Do not really execute, just print the commands. |
|
off => forces rebuild of every compilation unit.on (default) => rebuild only units whose input files have changed.verbose => like “on” but print a reason for every unit being rebuilt. |
|
Invoke single-file analysis for given source file. |
|
Pass argument to cafeCC when compiling. |
|
Pass argument to cafeCC when linking. |
|
The target to analyze (default “Release”). |
6.4.1.6. build_compile_commands¶
build_compile_commands reads compile_command.json files
and issues the necessary calls to cafeCC.
Note
build_compile_commands internally calls cafeCC. Therefore all
configuration issues that are relevant for cafeCC apply here as well.
Similarly, for the calls to the back-end cafe, the respective configuration
is used. Please refer to the Configuration sections of these tools for more
information.
Command-Line Switches¶
usage: build_compile_commands [-h] [--clean] [-B basepath] [-j [N]] [-n] [-r]
[--incremental INCREMENTAL] [--single_file filename]
[--carg argument] [--larg argument]
[--exclude pattern] [--include pattern]
[--output_filename output_filename]
[--setup_compiler_profile]
[--compiler_profile_path compiler_config.json]
compile_commands.json
|
The compile_commands.json to analyze. |
|
Cleans project (instead of building). |
|
Set source base path (only set if you understand the implications). |
|
Execute with N processes in parallel. N=1 if switch omitted, use the Default Parallelism logic if N omitted. |
|
Do not really execute, just print the commands. |
|
off => forces rebuild of every compilation unit.on (default) => rebuild only units whose input files have changed.verbose => like “on” but print a reason for every unit being rebuilt. |
|
Invoke single-file analysis for given source file. |
|
Pass argument to cafeCC when compiling. |
|
Pass argument to cafeCC when linking. |
|
Exclude files matching globbing pattern from compilation. Can be used multiple times. |
|
Limit compilation to files matching globbing pattern. Can be used multiple times. |
|
Specify the output filename to be generated after linking (default: |
|
Create compiler profile according to commands/arguments in compile_commands.json |
|
Configuration layer to store the compiler configuration. (default: most local layer) |
6.4.1.7. build_ewp¶
build_ewp reads IAR Systems Embedded Workbench project files for C/C++ projects
(*.ewp) and issues the necessary calls to cafeCC.
Note
build_ewp internally calls cafeCC. Therefore all configuration
issues that are relevant for cafeCC apply here as well. Similarly, for the
calls to the back-end cafe, the respective configuration is used. Please
refer to the Configuration sections of these tools for more information.
Command-Line Switches¶
usage: build_ewp [-h] [--clean] [-B basepath] [-j [N]] [-n] [-r]
[--incremental INCREMENTAL] [--single_file filename]
[--carg argument] [--larg argument] [--config config]
[--outprefix prefix] [--skip_prebuild] [--skip_postbuild]
[--toolkit_dir toolkit_dir] [--ew_dir ew_dir]
[--eww_file eww_file]
project.ewp
|
The project to analyze. |
|
Cleans project (instead of building). |
|
Set source base path (only set if you understand the implications). |
|
Execute with N processes in parallel. N=1 if switch omitted, use the Default Parallelism logic if N omitted. |
|
Do not really execute, just print the commands. |
|
off => forces rebuild of every compilation unit.on (default) => rebuild only units whose input files have changed.verbose => like “on” but print a reason for every unit being rebuilt. |
|
Invoke single-file analysis for given source file. |
|
Pass argument to cafeCC when compiling. |
|
Pass argument to cafeCC when linking. |
|
The configuration to analyze (default: |
|
Append prefix to output directory structure. |
|
Skip the prebuild action, if present. |
|
Skip the postbuild action, if present. |
|
Location of IAR toolkit directory (required for |
|
Location of the Embedded Workbench directory (required for |
|
Location of the .eww file (required for |
6.4.1.8. build_gpj¶
build_gpj reads Green Hills Software MULTI project files for C/C++ projects
(*.gpj) and issues the necessary calls to cafeCC. This is done by
invoking gpjmodify to create a Makefile and then make to do the
actual compilation via cafeCC.
Note
build_gpj internally calls cafeCC. Therefore all configuration
issues that are relevant for cafeCC apply here as well. Similarly, for the
calls to the back-end cafe, the respective configuration is used. Please
refer to the Configuration sections of these tools for more information.
Command-Line Switches¶
usage: build_gpj [-h] [-B basepath] [-j [N]] [-E env=var] [--make make]
[--gpjmodify gpjmodify] [--makefile_name Makefile]
[--target target]
project.gpj
|
The project to analyze. |
|
Set source base path. |
|
Execute with N processes in parallel. N=1 if switch omitted, use the Default Parallelism logic if N omitted. |
|
Set environment variable to pass to gpjmodify. |
|
Location of the make tool to use. |
|
Location of the gpjmodify tool to use. |
|
Name of the Makefile that gpjmodify generates by default. |
|
Name of the Makefile target to build. |
6.4.1.9. build_sln¶
build_sln analyzes Microsoft Visual Studio solution files for C/C++ projects
(*.sln) and invokes MSBuild to issue the necessary calls to
cafeCC.
Note
build_sln internally calls cafeCC. Therefore all configuration
issues that are relevant for cafeCC apply here as well. Similarly, for the
calls to the back-end cafe, the respective configuration is used. Please
refer to the Configuration sections of these tools for more information.
Command-Line Switches¶
usage: build_sln [-msbuild:msbuild.exe] solution.sln [-t:<target>] [-p:name=value]
|
Specify the |
|
The solution to analyze. |
|
MSBuild target to run (default: |
|
Sets an MSBuild property. |
|
Read command-line arguments from a response file. |
Additional command-line options are passed through to MSBuild.
6.4.1.10. build_uvprojx¶
build_uvprojx reads Keil µVision project files for C/C++ projects
(*.uvprojx and the older *.uvproj files) and issues the necessary
calls to cafeCC.
Note
build_uvprojx internally calls cafeCC. Therefore all configuration
issues that are relevant for cafeCC apply here as well. Similarly, for the
calls to the back-end cafe, the respective configuration is used. Please
refer to the Configuration sections of these tools for more information.
Command-Line Switches¶
usage: build_uvprojx [-h] [--clean] [-B basepath] [-j [N]] [-n]
[--incremental INCREMENTAL] [--single_file filename]
[--aarg argument] [--carg argument] [--larg argument]
[--tools_ini tools_ini] [--output_dir_prefix prefix]
[--output_dir_suffix suffix] [--create_rte_header] [-k]
[--skip_before_compile_prog [N ...]]
[--skip_before_make_prog [N ...]]
[--skip_after_make_prog [N ...]]
project.uvprojx [targetname]
|
Cleans the intermediate directory from intermediate build files. |
|
Set source base path (only set if you understand the implications). |
|
Execute with N processes in parallel. N=1 if switch omitted, use the Default Parallelism logic if N omitted. |
|
Do not execute commands, just print them. |
|
off => forces rebuild of every compilation unit.on (default) => rebuild only units whose input files have changed.verbose => like “on” but print a reason for every unit being rebuilt. |
|
Invoke single-file analysis for given source file. |
|
Pass argument to cafeCC when assembling. |
|
Pass argument to cafeCC when compiling. |
|
Pass argument to cafeCC when linking. |
|
Set tools.ini of Keil installation to use. |
|
Append prefix directory to output directory structure (if OutputDirectory is not absolute). |
|
Append suffix directory to output directory structure. |
|
Create RTE Components Header file. Usually done by Keil IDE. (EXPERIMENTAL) |
|
Keep flying despite compile errors. |
|
The project file to analyze. |
|
The target defined in the project file to analyze. |
|
Skip program from |
|
Skip program from |
|
Skip program from |
The skip options cannot directly precede project.uvprojx or
targetname.
6.4.1.11. build_vcxproj¶
build_vcxproj analyzes Microsoft Visual Studio project files for C/C++ projects
(*.vcxproj) and invokes MSBuild to issue the necessary calls to
cafeCC.
Note
build_vcxproj internally calls cafeCC. Therefore all configuration
issues that are relevant for cafeCC apply here as well. Similarly, for the
calls to the back-end cafe, the respective configuration is used. Please
refer to the Configuration sections of these tools for more information.
Command-Line Switches¶
usage: build_vcxproj [-msbuild:msbuild.exe] [-solution:solution.sln]
project.vcxproj [-t:<target>] [-p:name=value]
|
Specify the |
|
Provides a solution as context when building a single project. Used to detect the configuration/platform to use for building dependent projects. |
|
The project to analyze. |
|
MSBuild target to run (default: |
|
Sets an MSBuild property. |
|
Read command-line arguments from a response file. |
Additional command-line options are passed through to MSBuild.
6.4.1.12. irWRAPPERS¶
The following tools exist: irAR, irCC, irCP, irCXX,
irLD, irLIBTOOL, irLN, irLTORANLIB, irMT,
irMV, irNVCC, irOBJCOPY, irOBJDUMP, irRANLIB,
irSIZE, irSTRIP.
Those wrapper scripts can be used in-place of their native counterparts in order to
compile native objects and Axivion IR at the same time.
You can influence how the wrappers operate with environment variables
COMPILE_ONLY and COMPILE_ONLYIR. If those variables are set to
any value (even 0 or false or OFF, etc.) they are considered as set.
The following table summarizes the behavior of the irWRAPPER tools with
regard to those variables:
COMPILE_ONLY
COMPILE_ONLYIRMeaning
unset
unset
Compiles native objects and Axivion IR (with suffix
.ir).set
unset
Compiles only native objects (as if not using the wrapper at all).
unset
set
Compiles only Axivion IR (with original filenames).
set
set
Behaves as if
COMPILE_ONLYIRwas not set (i.e. compiles only native).
In the following table, the different wrapper tools and their behavior and use is explained:
|
Replacement for the native archiver (as configured via
|
|
Replacement for the native C compiler (as configured via
The contents of environment variables The content of environment variable Note: When used in linking context, still |
|
Replacement for the |
|
Replacement for the native C++ compiler (as configured via
The contents of environment variables The content of environment variable Note: When used in linking context, still |
|
Replacement for the native linker (as configured via
The contents of environment variables |
|
Replacement for the native |
|
Replacement for the |
|
Replacement for the native |
|
Replacement for the Microsoft |
|
Replacement for the |
|
Replacement for the native CUDA compiler (as configured via
The contents of environment variables The content of environment variable |
|
Replacement for the native |
|
Replacement for the native |
|
Replacement for the native |
|
Replacement for the native |
|
Replacement for the native |
Command-Line Switches¶
The command-line switches of the those irWRAPPERS tools are the same as for
their native counterparts respectively.
6.4.1.13. axivion_injector¶
axivion_injector can be used to prepend native compiler/linker calls to
inject the Axivion compiler/linker. Depending on further parameters, the behavior
can be selected as desired.
Command-Line Switches¶
usage: axivion_injector MODE [KEY=VALUE...] CMD [ARGS...]
|
|
|
Invoke native compiler. |
|
Invoke Axivion compiler. |
|
Append .ir to Axivion objects. |
|
No additional error message for native failures. |
|
Continue with IR compilation for native failures. |
Examples¶
axivion_injector native gcc -Iinclude -DHAVE_FOO=1 -o main.o -c main.cpp
axivion_injector ir gcc -Iinclude -DHAVE_FOO=1 -o main.o -c main.cpp
axivion_injector native_and_ir ignore_native_exitcode=true gcc -Iinclude -DHAVE_FOO=1 -o main.o -c main.cpp
axivion_injector cdt ${COMMAND} ${FLAGS} ${OUTPUT_FLAG}${OUTPUT_PREFIX}${OUTPUT} ${INPUTS}
6.4.1.14. srcCP¶
srcCP can be used in case source files are copied from their
version-controlled location to a temporary/build location and used during the
compilation from there. In such case, the files cannot be looked up in the VCS by
default because they are used from a different path.
Using srcCP you can patch the copied source files with a #line
directive (either “inplace” or when copying or patching an existing copy) or an
#include directive (only when copying or patching an existing copy).
This way you can create a “back mapping” from the copied source files to the
original source files that are under version control.
Command-Line Switches¶
usage: srcCP [-h] [--flatten | --patch | --patch-inplace | --revert] [--only-once]
[--include] [-a] [-v] [--exts EXTLIST]
OBJECT [OBJECT ...]
|
File or directory to copy/patch/revert. Can be specified twice, and if the last
|
|
Flatten out source directory structure in destination when copying. If not specified, source directory structure will be maintained in destination when copying (default). |
|
Patches an already copied directory structure compared with its original. |
|
Patches files (individual or recursing into directories) “inplace”. |
|
Reverts files (individual or recursing into directories). |
|
Do not patch again if file already starts with |
|
Generate an |
|
Preserves file attributes (mode, atime, mtime, flags) in copy-mode. |
|
Print files as they are copied/patched/reverted. |
|
File extensions to patch (comma-separated string list, default:
|
If neither --patch-inplace nor --revert is given, then the
last positional argument denotes the destination file or directory as we are operating
in copy-mode. If --include is specified, then an #include directive
is generated instead of a #line directive (cannot be used together with
--patch-inplace). If --only-once is specified, then
--patch-inplace has also to be specified. If OBJECT starts
with @, it is treated as response file with further switches, filenames, or
directory names inside.
Examples¶
#line directives while copying them¶srcCP comp1/inc comp2/inc output/generated
#line directives after they have been copied¶srcCP --patch comp1/inc comp2/inc output/generated
#include directives while copying them¶srcCP --include comp1/inc comp2/inc output/generated
#include directives after they have been copied¶srcCP --patch --include comp1/inc comp2/inc output/generated
srcCP --revert output/generated