Ignoring function declaration?
Hi there, first off thanks to the developer for the very cool open source tool!
At the moment, im trying use clangql for a project, and have this issue when a file contains both standalone function declarations and function definition, clangql would retrieve the function declaration instead of the definition.
For example running this query on Nic Baker's Clay: clangql -f clay/clay.c -q "select * from functions -o json gives me this output on the last element:
"name":"Clay__GetParentElementId","return_type":"uint32_t","signature":"uint32_t (void)","source_loc":"clay/clay.c:890:26"}
However, looking at the source code, this is just the function declaration, and the full definition is provided in line 1280:
uint32_t Clay__GetParentElementId(void) {
Clay_Context* context = Clay_GetCurrentContext();
return Clay_LayoutElementArray_Get(&context->layoutElements, Clay__int32_tArray_GetValue(&context->openLayoutElementStack, context->openLayoutElementStack.length - 2))->id;
}
In my current use case I need to retrieve only the full function definitions. Any ideas on how to go around this?
Disclaimer: I'm not familiar with C programming, but my current project require me to dig into C source codes.
Kindly thanks, Afrizal
Hello @afrizalhasbi,
Thank you for creating this issue. I added two matches for function def and decl.
select * from functions where m_function(ast_function, m_function_decl());
select * from functions where m_function(ast_function, m_function_def());
I will publish a new release now
Thank you, Amr Hesham
Hi there, first off thank you for adding the feature quite quickly!
Running the query again on my part it appears that the same issue persists. So my original issue was that the full functions table, once they index a function declaration, ignores the subsequent function definition. So when I run select * from functions I'll get the same table full of function declaration and not definition, and adding where m_function(ast_function, m_function_def()); wouldn't give me the definitions of those declared functions (as they are not included in the table).
Any chance that you could help out on this? I would be greatly obliged.
Afrizal
Hello @afrizalhasbi,
Can you write a small sample so we can fix all issues around it, for example, i was testing using
int foo();
int foo() { return 0; }
I am interested to fix the problem and provide the requirements helper and matchers
Thank you, Amr
Hi there, so the file I'm having trouble is this clay.h file.
So as you can see, the source_loc is in line 890:
clangql -f clay.h -q "select * from functions where name = 'Clay__GetParentElementId'"
╭──────────────────────────┬─────────────────┬─────────────┬─────────────────┬───────────────╮
│ name ┆ signature ┆ return_type ┆ ast_function ┆ source_loc │
╞══════════════════════════╪═════════════════╪═════════════╪═════════════════╪═══════════════╡
│ Clay__GetParentElementId ┆ uint32_t (void) ┆ uint32_t ┆ uint32_t (void) ┆ clay.h:890:26 │
╰──────────────────────────┴─────────────────┴─────────────┴─────────────────┴───────────────╯
However the Clay__GetParentElementId is defined in line 1280:
//this should be in line 890
CLAY_DLL_EXPORT uint32_t Clay__GetParentElementId(void);
// this should be in line 1280
uint32_t Clay__GetParentElementId(void) {
Clay_Context* context = Clay_GetCurrentContext();
return Clay_LayoutElementArray_Get(&context->layoutElements, Clay__int32_tArray_GetValue(&context->openLayoutElementStack, context->openLayoutElementStack.length - 2))->id;
}
Actually looking at line 890 again I notice there was a macro call before the function declaration. I tried isolating it the lines 890 and 1280 like this, and it somehow worked properly:
// file saved as clay2.h
#ifdef CLAY_DLL
#define CLAY_DLL_EXPORT __declspec(dllexport) __stdcall
#else
#define CLAY_DLL_EXPORT
#endif
CLAY_DLL_EXPORT uint32_t Clay__GetParentElementId(void);
uint32_t Clay__GetParentElementId(void) {
Clay_Context* context = Clay_GetCurrentContext();
return Clay_LayoutElementArray_Get(&context->layoutElements, Clay__int32_tArray_GetValue(&context->openLayoutElementStack, context->openLayoutElementStack.length - 2))->id;
}
clangql -f clay2.h -q "select * from functions where name = 'Clay__GetParentElementId'"
╭──────────────────────────┬────────────┬─────────────┬──────────────┬──────────────╮
│ name ┆ signature ┆ return_type ┆ ast_function ┆ source_loc │
╞══════════════════════════╪════════════╪═════════════╪══════════════╪══════════════╡
│ Clay__GetParentElementId ┆ int (void) ┆ int ┆ int (void) ┆ clay2.h:7:26 │
├╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌┤
│ Clay__GetParentElementId ┆ int (void) ┆ int ┆ int (void) ┆ clay2.h:9:10 │
╰──────────────────────────┴────────────┴─────────────┴──────────────┴──────────────╯
clangql -f clay2.h -q "select * from functions where m_function(ast_function, m_function_def());"
╭──────────────────────────┬────────────┬─────────────┬──────────────┬──────────────╮
│ name ┆ signature ┆ return_type ┆ ast_function ┆ source_loc │
╞══════════════════════════╪════════════╪═════════════╪══════════════╪══════════════╡
│ Clay__GetParentElementId ┆ int (void) ┆ int ┆ int (void) ┆ clay2.h:9:10 │
╰──────────────────────────┴────────────┴─────────────┴──────────────┴──────────────╯
However as I've said before, in the original clay.h file, the Clay__GetParentElementId is only indexed in the line 890 function declaration, when it is defined in line 1280.
Again, I'm not familiar with C programming, so I might be confused here. Thank you and apologies if I am not quite clear.
Afrizal
it somehow worked properly
Yes, it's because the macro disables some part of the code, for example if you run
select * from functions where m_function(ast_function, m_function_def()) and name = 'Clay__GetParentElementId';
On the original clay.h file it will not find the function, however it exists, but removed by macro check, I will try to see what can I do with macros so we can run query on part of the code even if it disabled
Thank you, Amr
Thank you!
Afrizal