Translator Patch +---+ | | +----+ | | Request pattern to search for | | | | ----------------------------------> | | | | | | | | Return pattern | | | | <--------------------------------- | | | | | | | | ---+ | | | | | Find | | | | | captures | | | | | in src | | | | <--+ | | | | | | | | Return captures found | | | | ----------------------------------> | | | | | | | | +-- | | | | Use capture | | | | | info to | | | | | build new | | | | | syntax str | | | | | +-> | | | | | | | | Return new syntax string to patch | | | | <---------------------------------- | | | | | | | | ---+ | | | | | Replace old | | | | | with new syntax | | | | | at all occurrences | | | | | in the file. | | | | <--+ | | | | | | +---+ +----+
Most of the C++ syntax is simple to translate. But unfortunately the one exception are C++ templates.
Translating template functions and calls from C++ to C is tricky. Since each template has a number of actual implementations we do the following.
fcn_[template_param_0]_[template_param_1]()
Example
This C++ template function
template<unsigned X> void fcn() { unsigned a = X * 8; }
becomes
#define DEFINE_FCN(X) \ void fcn ## _ ## X() { \ unsigned a = X * 8; \ }
To define an implementation where X = 0
we do
DEFINE_FCN(0)
To call this implementation we call fcn_0()
.
(There is a special case when a template parameter is passed on to a template call. But this is explained in the code.)
In our C++ code a template function can be called with different template parameters. For each of those calls we need to define a template implementation in C.
To do that we first scan source files for calls to template functions (TemplateCollector.py
does this). For each unique call we check the parameter list. Knowing the parameter list we can now define a C function which uses exactly those parameters. For the definition we use a macro as above.
Example
Within this C++ code we see two template function calls:
void main() { fcn<0>(); fcn<4>(); }
With the knowledge that once parameter 1
and once parameter 4
was passed to the template, we can define the implementations with the help of our DEFINE_FCN
macro.
DEFINE_FCN(0) DEFINE_FCN(4)
Within the C code we can now call those with fcn_0()
and fcn_4()
.