4

I would like to know if it's possible to insert a global variable declaration with a gcc plugin. For example if I have the following code:

test.c:

int main(void) {
  return 0;
}

and I want to transform it into:

int fake_var;

int main(void) {
  return 0;
}

Is that possible? If it's possible, in which pass and how can I do it?

artless noise
  • 21,212
  • 6
  • 68
  • 105
Andres Tiraboschi
  • 543
  • 1
  • 7
  • 17
  • What are you trying to achieve? What do you mean by a "gcc plugin"? gcc has no integrated text editor. – Jens Gustedt Sep 23 '14 at 15:50
  • 3
    by gcc plugin i'm talking about this: https://gcc.gnu.org/onlinedocs/gccint/Plugins.html#Plugins – Andres Tiraboschi Sep 23 '14 at 22:46
  • @AndresTiraboschi I am working on something probably like what you were working on, I wish I could ask you some questions, tell me if you get this comment – Othman Benchekroun Apr 08 '15 at 12:30
  • @Othman : Hi, what are you trying to do? – Andres Tiraboschi Apr 08 '15 at 13:59
  • @AndresTiraboschi Hi, thanks for showing, I need to swap the location of two fields of a class. The reason behind this is to reorder the elements of the class to avoid the padding. Example : `class A{ char c; int i;};` must turn to `class A{ int i; char c;};` my pass goes after ssa, I am looping trough the global namespaces to find names. FOr the moment, I am able to detect a bad order of fields, but I have no idea how to change it !! Any help is welcome and thanks anyway !! – Othman Benchekroun Apr 08 '15 at 14:38
  • @AndresTiraboschi take a look here : http://stackoverflow.com/questions/29488782/use-gcc-plugins-to-modify-the-order-of-variable-declarations – Othman Benchekroun Apr 08 '15 at 15:06
  • @Othman : The struct is defined during the parsing, I think that the easiest way to modify it there. I'm not sure about that because never tried to do something similiar, but maybe you can do something there. Take a look with this plugin event PLUGIN_FINISH_TYPE. Maybe is possible to do something. – Andres Tiraboschi Apr 08 '15 at 15:35
  • @AndresTiraboschi Thank you again for your answer, I will take a look at that, but I have just started using the gcc plugins and I am not that good, can you tell, what struct/functions should I use to parse/modify types using that event ? – Othman Benchekroun Apr 09 '15 at 07:16
  • @Othman : in that event you'll get a tree that represents a type. You should try to modify the order of the fields of that tree. I never worked with that but maybe the fields are in form of a linked list (tree(tree(...))). You should try to see in gdb where in the tree given by the plugin event are the trees representing the types char and int from your example above. A very important question: did you PLUGIN_FINISH_TYPE is triggerd when the compiler ends compiling a class or struct? If not maybe you should try to add a plugin event to gcc to hook that. – Andres Tiraboschi Apr 09 '15 at 15:33
  • @AndresTiraboschi I didn't get your question at the end, and what is the tree representing the type that will be given me ?? ( how to get it ) – Othman Benchekroun Apr 09 '15 at 15:42
  • @Othman : in the plugin you register a callback (register_callback (plugin_name, PLUGIN_FINISH_TYPE, myCallback, NULL)) and my Callback is a function: (void plugin_callback_func(void *gcc_data, void *user_data)), in that case gcc_data actualy is of type tree*. – Andres Tiraboschi Apr 09 '15 at 20:19

5 Answers5

2

Using GCC -D option u can pass a value to a C program. Eg:

int main()
{
printf("global decl %d\n", gvar);
}

gcc -Dgvar=10 gcc.c

This may give a closest behaviour you are looking for though this is not equivalent to a global variable declaration. This is a macro substitution at compile time.

deadbeef
  • 621
  • 6
  • 20
2

I think you'll want to take a look at varpool_add_new_variable() in varpool.c. You should be able to pass a declaration built with type VAR_DECL to it. Similarly, take a look at add_new_static_var(), but I think the former is what you want, as it was added specifically to allow declaring globals in the middle/back end.

1

below there is an example of create a global integer var:

//add_new_static_var, in cgraph.h
tree global_var = add_new_static_var(integer_type_node);
//if you want to name the var:
tree name = get_identifier("my_global_name");
DECL_NAME(global_var) = name;
/*AND if you have thought to use in another subsequent compilation, you 
  will need to give it an assembler name like this*/
change_decl_assembler_name(global_var, name);

Keep in mind that in another compilation that it's supposed you to link after with a previous compilation you will need to declare the global var too, but you will have to declare all var with DECL_EXTERNAL(global_var) = 1 in all compilation minus the original, and only in one compilation (i.e, the original: the compilation that hold the original var ) you must only to add the propertie TREE_PUBLIC(global_var) = 1

Jordy Baylac
  • 510
  • 6
  • 18
0

Ehm, no. Don't. Why would you want to? You can't use it.

The closest you can get is to define the variable in a new .c file and link it in separately, but it would still have to be declared (with extern) in test.c for test.c to use it.

Lightness Races in Orbit
  • 378,754
  • 76
  • 643
  • 1,055
  • I know i can't use but that was the easiest example. I wanted to know if it's possible to do that declaration with a plugin. When you said no is because is impossible or because i has no sense? – Andres Tiraboschi Sep 24 '14 at 19:35
  • 1
    Why couldn't other code inserted by the plugin use it? –  Sep 25 '14 at 00:31
0

you can create a file that contains the code you want to add to the top of the input file and use the -include yourfile option.

that advises the preprocessor to assume an #include "yourfile" at the top of the input file.

see this question:
Include header files using command line option?

But you have to separately build that c file since this file will be added to all compilation units.

Community
  • 1
  • 1
vlad_tepesch
  • 6,681
  • 1
  • 38
  • 80