1  /* This plugin tests the correct operation of a PLUGIN_START_UNIT callback.
       2   * By the time a PLUGIN_START_UNIT callback is invoked, the frontend 
       3   * initialization should have completed. At least the different *_type_nodes
       4   * should have been created. This plugin creates an artificial global 
       5   * interger variable.
       6   * 
       7  */
       8  #include "gcc-plugin.h"
       9  #include "config.h"
      10  #include "system.h"
      11  #include "coretypes.h"
      12  #include "tm.h"
      13  #include "tree.h"
      14  #include "stringpool.h"
      15  #include "toplev.h"
      16  #include "basic-block.h"
      17  #include "hash-table.h"
      18  #include "vec.h"
      19  #include "ggc.h"
      20  #include "basic-block.h"
      21  #include "tree-ssa-alias.h"
      22  #include "internal-fn.h"
      23  #include "tree-eh.h"
      24  #include "gimple-expr.h"
      25  #include "is-a.h"
      26  #include "gimple.h"
      27  #include "tree.h"
      28  #include "tree-pass.h"
      29  #include "intl.h"
      30  
      31  int plugin_is_GPL_compatible;
      32  static tree fake_var = NULL;
      33  
      34  static bool
      35  gate_start_unit (void)
      36  {
      37    return true;
      38  }
      39  
      40  static void start_unit_callback (void *gcc_data, void *user_data)
      41  {
      42    static const struct ggc_root_tab root[] = {
      43      {
      44        &fake_var,
      45        1,
      46        sizeof (fake_var),
      47        >_ggc_mx_tree_node,
      48        >_pch_nx_tree_node
      49      },
      50      LAST_GGC_ROOT_TAB
      51    };
      52  
      53    register_callback ("start_unit", PLUGIN_REGISTER_GGC_ROOTS, NULL,
      54  		     (void *)root);
      55    if (integer_type_node) {
      56      fake_var = build_decl (UNKNOWN_LOCATION, VAR_DECL, 
      57                             get_identifier ("_fake_var_"),
      58                             integer_type_node);
      59      TREE_PUBLIC (fake_var) = 1;
      60      DECL_ARTIFICIAL (fake_var) = 1;
      61    }
      62  }
      63  
      64  static void finish_unit_callback (void *gcc_data, void *user_data)
      65  {
      66    if (fake_var == NULL) {
      67      printf ("fake_var not created \n");
      68      return;
      69    }
      70    if (TREE_CODE (fake_var) != VAR_DECL) {
      71      printf ("fake_var not a VAR_DECL \n");
      72      return;
      73    }
      74    if (TREE_CODE (TREE_TYPE (fake_var)) != INTEGER_TYPE) {
      75      printf ("fake_var not INTEGER_TYPE \n");
      76      return;
      77    }
      78    if (DECL_ARTIFICIAL (fake_var) == 0) {
      79      printf ("fake_var not ARTIFICIAL \n");
      80      return;
      81    }
      82  }
      83  
      84  int plugin_init (struct plugin_name_args *plugin_info,
      85                   struct plugin_gcc_version *version)
      86  {
      87    register_callback ("start_unit", PLUGIN_START_UNIT, &start_unit_callback, NULL);
      88    register_callback ("finish_unit", PLUGIN_FINISH_UNIT, &finish_unit_callback, NULL);
      89    return 0;
      90  }