Skip to content

Commit 645a034

Browse files
Krishna-13-cybervgvassilev
authored andcommitted
Add C-C++ Interoperability tutorial in CppinterOp docs
1 parent e598aef commit 645a034

File tree

1 file changed

+121
-1
lines changed

1 file changed

+121
-1
lines changed

docs/tutorials.rst

Lines changed: 121 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -181,4 +181,124 @@ function is called, which is `callme` function in this case.
181181
The complete example can found below:
182182
`Example <https://github.com/compiler-research/pldi-tutorials-2023
183183
/blob/main/examples/p3-ex4/instantiate_cpp_template.py>`_.
184-
184+
185+
C:
186+
===
187+
188+
Include **p3-ex4-lib.h**, which contains the declarations for the functions used
189+
in this code. The detailed summary of header comes in the latter part.
190+
191+
192+
The variable Code is given as a C-style string, it contains the C++ code
193+
to be parsed. It has two classes, class `A` and a templated class `B` with a member
194+
function callme.
195+
196+
.. code-block:: C
197+
198+
const char* Code = "void* operator new(__SIZE_TYPE__, void* __p) noexcept;"
199+
"extern \"C\" int printf(const char*,...);"
200+
"class A {};"
201+
"\n #include <typeinfo> \n"
202+
"class B {"
203+
"public:"
204+
" template<typename T>"
205+
" void callme(T) {"
206+
" printf(\" Instantiated with [%s] \\n \", typeid(T).name());"
207+
" }"
208+
"};";
209+
210+
The main() begins with the call to **Clang_Parse** from interop library responsible
211+
for parsing the provided C++ code.
212+
213+
Next there a number of initializations, **Instantiation** is initialized to zero,
214+
it will be used to store the instantiated template. The **InstantiationArgs**
215+
is initialized to "A", it will be used as the argument when instantiating the template.
216+
`T` is initialized to zero, used to store the declaration of the type "T" used for
217+
instantiation.
218+
219+
.. code-block:: C
220+
221+
Decl_t Instantiation = 0;
222+
const char * InstantiationArgs = "A";
223+
Decl_t TemplatedClass = Clang_LookupName("B", /*Context=*/0);
224+
Decl_t T = 0;
225+
226+
This snippet checks command-line arguments were provided by the argc arguments.
227+
We take the first argument (`argv[1]`), parse it, then take the second argument
228+
(`argv[2]`) using **Clang_LookupName**, and reassigns **InstantiationArgs** to
229+
the third argument (`argv[3]`). In the else case, we decide to go with the "A".
230+
231+
The code proceeds to instantiate the template `B::callme` with the given
232+
type, using the **Clang_InstantiateTemplate** function from the
233+
library. The instantiated template is stored in the **Instantiation**.
234+
235+
.. code-block:: C
236+
237+
Instantiation = Clang_InstantiateTemplate(TemplatedClass, "callme", InstantiationArgs);
238+
239+
240+
A function pointer **callme_fn_ptr** is declared with a type `fn_def` that represents
241+
the function taking a `void*` argument and returning void. The result of
242+
**Clang_GetFunctionAddress** is casted by the function pointer.
243+
244+
.. code-block:: C
245+
246+
typedef void (*fn_def)(void*);
247+
fn_def callme_fn_ptr = (fn_def) Clang_GetFunctionAddress(Instantiation);
248+
249+
The code then creates an object of type `A` using **Clang_CreateObject**, and the
250+
pointer to this object is stored in `NewA`.
251+
252+
.. code-block:: C
253+
254+
void* NewA = Clang_CreateObject(T);
255+
256+
Then the function pointer **callme_fn_ptr** is called with the `NewA`, which
257+
calls the member function `B::callme` with the instantiated type. Thus, the instantiation
258+
happens with type `A` and we get the below result.
259+
260+
You get the **output** as :
261+
.. code-block:: bash
262+
263+
Instantiated with [1A]
264+
265+
In conclusion, this C code uses the CppInterOp library to dynamically instantiate
266+
templates and call member functions based on provided types. This example was to
267+
show how we can instantiate templates, in a similar manner we can use the
268+
CppInterOp library to use many other features and attributes of languages to
269+
interoperate.
270+
271+
**Header File:**
272+
273+
We wrap the library functions within the extern "C" for its usage in C programs.
274+
All the functions of the library which are to be used in the C program have to
275+
be under the extern C for the compiler to know the C++ code within.
276+
277+
.. code-block:: C
278+
279+
extern "C" {
280+
#endif // __cplusplus
281+
/// Process C++ code.
282+
///
283+
void Clang_Parse(const char* Code);
284+
285+
/// Looks up an entity with the given name, possibly in the given Context.
286+
///
287+
Decl_t Clang_LookupName(const char* Name, Decl_t Context);
288+
289+
/// Returns the address of a JIT'd function of the corresponding declaration.
290+
///
291+
FnAddr_t Clang_GetFunctionAddress(Decl_t D);
292+
293+
/// Allocates memory of underlying size of the passed declaration.
294+
///
295+
void * Clang_CreateObject(Decl_t RecordDecl);
296+
297+
/// Instantiates a given templated declaration.
298+
Decl_t Clang_InstantiateTemplate(Decl_t D, const char* Name, const char* Args);
299+
#ifdef __cplusplus
300+
}
301+
302+
303+
The complete example can found below:
304+
`Example <https://github.com/compiler-research/pldi-tutorials-2023/blob/main/examples/p3-ex4/p3-ex4.c>`_.

0 commit comments

Comments
 (0)