@@ -181,4 +181,124 @@ function is called, which is `callme` function in this case.
181
181
The complete example can found below:
182
182
`Example <https://github.com/compiler-research/pldi-tutorials-2023
183
183
/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