@@ -76,19 +76,81 @@ typedef struct loader_impl_c_type
7676
7777} * loader_impl_c;
7878
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+
7994typedef struct loader_impl_c_handle_base_type
8095{
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+ {
81111public:
82112 std::vector<std::string> files;
83113
84- virtual ~loader_impl_c_handle_base_type () {}
114+ virtual ~loader_impl_c_handle_file_type () {}
85115
86116 virtual bool recursive_includes () = 0;
87117
88118 virtual int discover (loader_impl impl, context ctx) = 0;
89119
90120 virtual const void *symbol (std::string &name) = 0;
91121
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+
92154 void add (const loader_path path, size_t size)
93155 {
94156 if (this ->is_ld_script (path, size) == false )
@@ -118,12 +180,65 @@ typedef struct loader_impl_c_handle_base_type
118180 return true ;
119181 }
120182
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;
122236
123237static void c_loader_impl_discover_symbols (void *ctx, const char *name, const void *addr);
124238static int c_loader_impl_discover_ast (loader_impl impl, loader_impl_c_handle_base c_handle, context ctx);
125239
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
127242{
128243public:
129244 TCCState *state;
@@ -207,7 +322,7 @@ typedef struct loader_impl_c_handle_tcc_type : loader_impl_c_handle_base_type
207322 virtual int discover (loader_impl impl, context ctx)
208323 {
209324 /* 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);
211326
212327 /* Parse the AST and register functions */
213328 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
222337
223338 return this ->symbols [name];
224339 }
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;
225344
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;
227347
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
229349{
230350public:
231351 dynlink lib;
@@ -385,15 +505,6 @@ typedef struct loader_impl_c_function_type
385505
386506} * loader_impl_c_function;
387507
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-
397508/* Retrieve the equivalent FFI type from type id */
398509static ffi_type *c_loader_impl_ffi_type (type_id id);
399510
@@ -681,9 +792,9 @@ void c_loader_impl_function_closure(ffi_cif *cif, void *ret, void *args[], void
681792
682793static void c_loader_impl_discover_symbols (void *ctx, const char *name, const void *addr)
683794{
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);
685796
686- c_handle-> symbols . insert (std::pair<std::string, const void *>(name, addr));
797+ symbols-> insert (std::pair<std::string, const void *>(name, addr));
687798}
688799
689800static 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
13051416 return 0 ;
13061417}
13071418
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)
13091420{
13101421 c_loader_impl_discover_visitor_data visitor_data = static_cast <c_loader_impl_discover_visitor_data>(data);
13111422
@@ -1353,91 +1464,9 @@ static int c_loader_impl_discover_ast(loader_impl impl, loader_impl_c_handle_bas
13531464 command_line_args.push_back (includes.back ().c_str ());
13541465 }
13551466
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 )
14191468 {
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 ;
14411470 }
14421471
14431472 return data.result ;
@@ -1455,7 +1484,7 @@ static int c_loader_impl_tcc_relocate(TCCState *state)
14551484loader_handle c_loader_impl_load_from_file (loader_impl impl, const loader_path paths[], size_t size)
14561485{
14571486 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 ();
14591488
14601489 if (c_handle->initialize (c_impl) == false )
14611490 {
@@ -1522,7 +1551,7 @@ loader_handle c_loader_impl_load_from_file(loader_impl impl, const loader_path p
15221551loader_handle c_loader_impl_load_from_memory (loader_impl impl, const loader_name name, const char *buffer, size_t size)
15231552{
15241553 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 ();
15261555
15271556 /* Apparently TCC has an unsafe API for compiling strings */
15281557 (void )size;
@@ -1544,7 +1573,9 @@ loader_handle c_loader_impl_load_from_memory(loader_impl impl, const loader_name
15441573 goto error;
15451574 }
15461575
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);
15481579
15491580 return c_handle;
15501581
0 commit comments