@@ -181,4 +181,124 @@ function is called, which is `callme` function in this case.
181181The 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