@@ -76,19 +76,81 @@ typedef struct loader_impl_c_type
76
76
77
77
} * loader_impl_c;
78
78
79
+ struct loader_impl_c_handle_base_type ;
80
+
81
+ typedef struct loader_impl_c_handle_base_type *loader_impl_c_handle_base;
82
+
83
+ typedef struct c_loader_impl_discover_visitor_data_type
84
+ {
85
+ loader_impl impl;
86
+ loader_impl_c_handle_base c_handle;
87
+ scope sp;
88
+ int result;
89
+
90
+ } * c_loader_impl_discover_visitor_data;
91
+
92
+ static CXChildVisitResult c_loader_impl_discover_visitor (CXCursor cursor, CXCursor, void *data);
93
+
79
94
typedef struct loader_impl_c_handle_base_type
80
95
{
96
+ public:
97
+ virtual ~loader_impl_c_handle_base_type () {}
98
+
99
+ virtual bool recursive_includes () = 0;
100
+
101
+ virtual int discover (loader_impl impl, context ctx) = 0;
102
+
103
+ virtual const void *symbol (std::string &name) = 0;
104
+
105
+ virtual int discover_visitor (std::vector<const char *> &command_line_args, void *data) = 0;
106
+
107
+ } * loader_impl_c_handle_base;
108
+
109
+ typedef struct loader_impl_c_handle_file_type : loader_impl_c_handle_base_type
110
+ {
81
111
public:
82
112
std::vector<std::string> files;
83
113
84
- virtual ~loader_impl_c_handle_base_type () {}
114
+ virtual ~loader_impl_c_handle_file_type () {}
85
115
86
116
virtual bool recursive_includes () = 0;
87
117
88
118
virtual int discover (loader_impl impl, context ctx) = 0;
89
119
90
120
virtual const void *symbol (std::string &name) = 0;
91
121
122
+ int discover_visitor (std::vector<const char *> &command_line_args, void *data)
123
+ {
124
+ for (std::string file : this ->files )
125
+ {
126
+ /* Define the command line arguments (simulating compiler flags) */
127
+ CXIndex index = clang_createIndex (0 , 1 );
128
+ CXTranslationUnit unit = NULL ;
129
+ CXErrorCode error = clang_parseTranslationUnit2 (
130
+ index,
131
+ file.c_str (),
132
+ command_line_args.data (), command_line_args.size (),
133
+ nullptr , 0 ,
134
+ CXTranslationUnit_None,
135
+ &unit);
136
+
137
+ if (error != CXError_Success)
138
+ {
139
+ log_write (" metacall" , LOG_LEVEL_ERROR, " Unable to parse translation unit of: %s with error code %d" , file.c_str (), error);
140
+ clang_disposeIndex (index);
141
+ return -1 ;
142
+ }
143
+
144
+ CXCursor cursor = clang_getTranslationUnitCursor (unit);
145
+ clang_visitChildren (cursor, c_loader_impl_discover_visitor, data);
146
+
147
+ clang_disposeTranslationUnit (unit);
148
+ clang_disposeIndex (index);
149
+ }
150
+
151
+ return 0 ;
152
+ }
153
+
92
154
void add (const loader_path path, size_t size)
93
155
{
94
156
if (this ->is_ld_script (path, size) == false )
@@ -118,12 +180,65 @@ typedef struct loader_impl_c_handle_base_type
118
180
return true ;
119
181
}
120
182
121
- } * loader_impl_c_handle_base;
183
+ } * loader_impl_c_handle_file;
184
+
185
+ typedef struct loader_impl_c_handle_memory_type : loader_impl_c_handle_base_type
186
+ {
187
+ public:
188
+ std::string name;
189
+ std::string buffer;
190
+
191
+ virtual ~loader_impl_c_handle_memory_type () {}
192
+
193
+ virtual bool recursive_includes () = 0;
194
+
195
+ virtual int discover (loader_impl impl, context ctx) = 0;
196
+
197
+ virtual const void *symbol (std::string &name) = 0;
198
+
199
+ int discover_visitor (std::vector<const char *> &command_line_args, void *data)
200
+ {
201
+ CXUnsavedFile unsaved_file;
202
+
203
+ /* Simulate an in-memory file */
204
+ unsaved_file.Filename = this ->name .c_str ();
205
+ unsaved_file.Contents = this ->buffer .c_str ();
206
+ unsaved_file.Length = this ->buffer .length ();
207
+
208
+ /* Define the command line arguments (simulating compiler flags) */
209
+ CXIndex index = clang_createIndex (0 , 1 );
210
+ CXTranslationUnit unit = NULL ;
211
+ CXErrorCode error = clang_parseTranslationUnit2 (
212
+ index,
213
+ this ->name .c_str (),
214
+ command_line_args.data (), command_line_args.size (),
215
+ &unsaved_file, 1 ,
216
+ CXTranslationUnit_None,
217
+ &unit);
218
+
219
+ if (error != CXError_Success)
220
+ {
221
+ log_write (" metacall" , LOG_LEVEL_ERROR, " Unable to parse translation unit of: %s with error code %d" , this ->name .c_str (), error);
222
+ clang_disposeIndex (index);
223
+ return -1 ;
224
+ }
225
+
226
+ CXCursor cursor = clang_getTranslationUnitCursor (unit);
227
+ clang_visitChildren (cursor, c_loader_impl_discover_visitor, data);
228
+
229
+ clang_disposeTranslationUnit (unit);
230
+ clang_disposeIndex (index);
231
+
232
+ return 0 ;
233
+ }
234
+
235
+ } * loader_impl_c_handle_memory;
122
236
123
237
static void c_loader_impl_discover_symbols (void *ctx, const char *name, const void *addr);
124
238
static int c_loader_impl_discover_ast (loader_impl impl, loader_impl_c_handle_base c_handle, context ctx);
125
239
126
- typedef struct loader_impl_c_handle_tcc_type : loader_impl_c_handle_base_type
240
+ template <typename T>
241
+ struct loader_impl_c_handle_tcc_type : T
127
242
{
128
243
public:
129
244
TCCState *state;
@@ -207,7 +322,7 @@ typedef struct loader_impl_c_handle_tcc_type : loader_impl_c_handle_base_type
207
322
virtual int discover (loader_impl impl, context ctx)
208
323
{
209
324
/* Get all symbols */
210
- tcc_list_symbols (this ->state , static_cast <void *>(this ), &c_loader_impl_discover_symbols);
325
+ tcc_list_symbols (this ->state , static_cast <void *>(&symbols ), &c_loader_impl_discover_symbols);
211
326
212
327
/* Parse the AST and register functions */
213
328
return c_loader_impl_discover_ast (impl, this , ctx);
@@ -222,10 +337,15 @@ typedef struct loader_impl_c_handle_tcc_type : loader_impl_c_handle_base_type
222
337
223
338
return this ->symbols [name];
224
339
}
340
+ };
341
+
342
+ typedef struct loader_impl_c_handle_tcc_type <loader_impl_c_handle_file_type> loader_impl_c_handle_tcc_file_type;
343
+ typedef loader_impl_c_handle_tcc_file_type *loader_impl_c_handle_tcc_file;
225
344
226
- } * loader_impl_c_handle_tcc;
345
+ typedef struct loader_impl_c_handle_tcc_type <loader_impl_c_handle_memory_type> loader_impl_c_handle_tcc_memory_type;
346
+ typedef loader_impl_c_handle_tcc_memory_type *loader_impl_c_handle_tcc_memory;
227
347
228
- typedef struct loader_impl_c_handle_dynlink_type : loader_impl_c_handle_base_type
348
+ typedef struct loader_impl_c_handle_dynlink_type : loader_impl_c_handle_file_type
229
349
{
230
350
public:
231
351
dynlink lib;
@@ -385,15 +505,6 @@ typedef struct loader_impl_c_function_type
385
505
386
506
} * loader_impl_c_function;
387
507
388
- typedef struct c_loader_impl_discover_visitor_data_type
389
- {
390
- loader_impl impl;
391
- loader_impl_c_handle_base c_handle;
392
- scope sp;
393
- int result;
394
-
395
- } * c_loader_impl_discover_visitor_data;
396
-
397
508
/* Retrieve the equivalent FFI type from type id */
398
509
static ffi_type *c_loader_impl_ffi_type (type_id id);
399
510
@@ -681,9 +792,9 @@ void c_loader_impl_function_closure(ffi_cif *cif, void *ret, void *args[], void
681
792
682
793
static void c_loader_impl_discover_symbols (void *ctx, const char *name, const void *addr)
683
794
{
684
- loader_impl_c_handle_tcc c_handle = static_cast <loader_impl_c_handle_tcc >(ctx);
795
+ std::map<std::string, const void *> *symbols = static_cast <std::map<std::string, const void *> * >(ctx);
685
796
686
- c_handle-> symbols . insert (std::pair<std::string, const void *>(name, addr));
797
+ symbols-> insert (std::pair<std::string, const void *>(name, addr));
687
798
}
688
799
689
800
static bool c_loader_impl_file_exists (const loader_path path)
@@ -1305,7 +1416,7 @@ static int c_loader_impl_discover_signature(loader_impl impl, loader_impl_c_hand
1305
1416
return 0 ;
1306
1417
}
1307
1418
1308
- static CXChildVisitResult c_loader_impl_discover_visitor (CXCursor cursor, CXCursor, void *data)
1419
+ CXChildVisitResult c_loader_impl_discover_visitor (CXCursor cursor, CXCursor, void *data)
1309
1420
{
1310
1421
c_loader_impl_discover_visitor_data visitor_data = static_cast <c_loader_impl_discover_visitor_data>(data);
1311
1422
@@ -1353,91 +1464,9 @@ static int c_loader_impl_discover_ast(loader_impl impl, loader_impl_c_handle_bas
1353
1464
command_line_args.push_back (includes.back ().c_str ());
1354
1465
}
1355
1466
1356
- /* TODO: Load from memory (discover from memory) */
1357
- /*
1358
- #include <clang-c/Index.h>
1359
- #include <stdio.h>
1360
- #include <stdlib.h>
1361
-
1362
- int main() {
1363
- const char *source_code =
1364
- "int add(int a, int b) {\n"
1365
- " return a + b;\n"
1366
- "}";
1367
-
1368
- // Simulate an in-memory file
1369
- CXUnsavedFile unsaved_file;
1370
- unsaved_file.Filename = "example.c";
1371
- unsaved_file.Contents = source_code;
1372
- unsaved_file.Length = (unsigned long)strlen(source_code);
1373
-
1374
- // Create index
1375
- CXIndex index = clang_createIndex(0, 0);
1376
-
1377
- // Parse translation unit from buffer (unsaved file)
1378
- CXTranslationUnit tu;
1379
- CXErrorCode err = clang_parseTranslationUnit2(
1380
- index,
1381
- "example.c", // filename for context (matches unsaved file)
1382
- NULL, 0, // command line args
1383
- &unsaved_file, 1, // unsaved files
1384
- CXTranslationUnit_None, // options
1385
- &tu
1386
- );
1387
-
1388
- if (err != CXError_Success) {
1389
- fprintf(stderr, "Failed to parse translation unit.\n");
1390
- return 1;
1391
- }
1392
-
1393
- // Get the cursor to the root of the translation unit
1394
- CXCursor cursor = clang_getTranslationUnitCursor(tu);
1395
-
1396
- // Visit each AST node
1397
- clang_visitChildren(
1398
- cursor,
1399
- [](CXCursor c, CXCursor parent, CXClientData client_data) {
1400
- CXString spelling = clang_getCursorSpelling(c);
1401
- CXString kind = clang_getCursorKindSpelling(clang_getCursorKind(c));
1402
- printf("Cursor: %s (%s)\n", clang_getCString(spelling), clang_getCString(kind));
1403
- clang_disposeString(spelling);
1404
- clang_disposeString(kind);
1405
- return CXChildVisit_Recurse;
1406
- },
1407
- NULL
1408
- );
1409
-
1410
- // Clean up
1411
- clang_disposeTranslationUnit(tu);
1412
- clang_disposeIndex(index);
1413
-
1414
- return 0;
1415
- }
1416
- */
1417
-
1418
- for (std::string file : c_handle->files )
1467
+ if (c_handle->discover_visitor (command_line_args, static_cast <void *>(&data)) != 0 )
1419
1468
{
1420
- /* Define the command line arguments (simulating compiler flags) */
1421
- CXIndex index = clang_createIndex (0 , 1 );
1422
- CXTranslationUnit unit = clang_parseTranslationUnit (
1423
- index,
1424
- file.c_str (),
1425
- command_line_args.data (), command_line_args.size (),
1426
- nullptr , 0 ,
1427
- CXTranslationUnit_None);
1428
-
1429
- if (unit == nullptr )
1430
- {
1431
- log_write (" metacall" , LOG_LEVEL_ERROR, " Unable to parse translation unit of: %s" , file.c_str ());
1432
- clang_disposeIndex (index);
1433
- return -1 ;
1434
- }
1435
-
1436
- CXCursor cursor = clang_getTranslationUnitCursor (unit);
1437
- clang_visitChildren (cursor, c_loader_impl_discover_visitor, static_cast <void *>(&data));
1438
-
1439
- clang_disposeTranslationUnit (unit);
1440
- clang_disposeIndex (index);
1469
+ return 1 ;
1441
1470
}
1442
1471
1443
1472
return data.result ;
@@ -1455,7 +1484,7 @@ static int c_loader_impl_tcc_relocate(TCCState *state)
1455
1484
loader_handle c_loader_impl_load_from_file (loader_impl impl, const loader_path paths[], size_t size)
1456
1485
{
1457
1486
loader_impl_c c_impl = static_cast <loader_impl_c>(loader_impl_get (impl));
1458
- loader_impl_c_handle_tcc c_handle = new loader_impl_c_handle_tcc_type ();
1487
+ loader_impl_c_handle_tcc_file c_handle = new loader_impl_c_handle_tcc_file_type ();
1459
1488
1460
1489
if (c_handle->initialize (c_impl) == false )
1461
1490
{
@@ -1522,7 +1551,7 @@ loader_handle c_loader_impl_load_from_file(loader_impl impl, const loader_path p
1522
1551
loader_handle c_loader_impl_load_from_memory (loader_impl impl, const loader_name name, const char *buffer, size_t size)
1523
1552
{
1524
1553
loader_impl_c c_impl = static_cast <loader_impl_c>(loader_impl_get (impl));
1525
- loader_impl_c_handle_tcc c_handle = new loader_impl_c_handle_tcc_type ();
1554
+ loader_impl_c_handle_tcc_memory c_handle = new loader_impl_c_handle_tcc_memory_type ();
1526
1555
1527
1556
/* Apparently TCC has an unsafe API for compiling strings */
1528
1557
(void )size;
@@ -1544,7 +1573,9 @@ loader_handle c_loader_impl_load_from_memory(loader_impl impl, const loader_name
1544
1573
goto error;
1545
1574
}
1546
1575
1547
- /* TODO: Load the buffer with the parser while iterating after loading it with TCC */
1576
+ c_handle->name = name;
1577
+ c_handle->name .append (" .c" );
1578
+ c_handle->buffer .assign (buffer, size);
1548
1579
1549
1580
return c_handle;
1550
1581
0 commit comments