plugin.cc 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929
  1. /* Library interface to C front end
  2. Copyright (C) 2014 Free Software Foundation, Inc.
  3. This file is part of GCC.
  4. GCC is free software; you can redistribute it and/or modify it under
  5. the terms of the GNU General Public License as published by the Free
  6. Software Foundation; either version 3, or (at your option) any later
  7. version.
  8. GCC is distributed in the hope that it will be useful, but WITHOUT ANY
  9. WARRANTY; without even the implied warranty of MERCHANTABILITY or
  10. FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
  11. for more details.
  12. You should have received a copy of the GNU General Public License
  13. along with GCC; see the file COPYING3. If not see
  14. <http://www.gnu.org/licenses/>. */
  15. #include <cc1plugin-config.h>
  16. #undef PACKAGE_NAME
  17. #undef PACKAGE_STRING
  18. #undef PACKAGE_TARNAME
  19. #undef PACKAGE_VERSION
  20. #include "../gcc/config.h"
  21. #undef PACKAGE_NAME
  22. #undef PACKAGE_STRING
  23. #undef PACKAGE_TARNAME
  24. #undef PACKAGE_VERSION
  25. #include "gcc-plugin.h"
  26. #include "system.h"
  27. #include "coretypes.h"
  28. #include "stringpool.h"
  29. #include "gcc-interface.h"
  30. #include "hash-set.h"
  31. #include "machmode.h"
  32. #include "vec.h"
  33. #include "double-int.h"
  34. #include "input.h"
  35. #include "alias.h"
  36. #include "symtab.h"
  37. #include "options.h"
  38. #include "wide-int.h"
  39. #include "inchash.h"
  40. #include "tree.h"
  41. #include "fold-const.h"
  42. #include "stor-layout.h"
  43. #include "c-tree.h"
  44. #include "toplev.h"
  45. #include "timevar.h"
  46. #include "hash-table.h"
  47. #include "tm.h"
  48. #include "c-family/c-pragma.h"
  49. #include "c-lang.h"
  50. #include "diagnostic.h"
  51. #include "langhooks.h"
  52. #include "langhooks-def.h"
  53. #include "callbacks.hh"
  54. #include "connection.hh"
  55. #include "rpc.hh"
  56. #ifdef __GNUC__
  57. #pragma GCC visibility push(default)
  58. #endif
  59. int plugin_is_GPL_compatible;
  60. #ifdef __GNUC__
  61. #pragma GCC visibility pop
  62. #endif
  63. // This is put into the lang hooks when the plugin starts.
  64. static void
  65. plugin_print_error_function (diagnostic_context *context, const char *file,
  66. diagnostic_info *diagnostic)
  67. {
  68. if (current_function_decl != NULL_TREE
  69. && DECL_NAME (current_function_decl) != NULL_TREE
  70. && strcmp (IDENTIFIER_POINTER (DECL_NAME (current_function_decl)),
  71. GCC_FE_WRAPPER_FUNCTION) == 0)
  72. return;
  73. lhd_print_error_function (context, file, diagnostic);
  74. }
  75. static unsigned long long
  76. convert_out (tree t)
  77. {
  78. return (unsigned long long) (uintptr_t) t;
  79. }
  80. static tree
  81. convert_in (unsigned long long v)
  82. {
  83. return (tree) (uintptr_t) v;
  84. }
  85. struct decl_addr_value
  86. {
  87. tree decl;
  88. tree address;
  89. };
  90. struct decl_addr_hasher : typed_free_remove<decl_addr_value>
  91. {
  92. typedef decl_addr_value value_type;
  93. typedef decl_addr_value compare_type;
  94. static inline hashval_t hash (const value_type *);
  95. static inline bool equal (const value_type *, const compare_type *);
  96. };
  97. inline hashval_t
  98. decl_addr_hasher::hash (const value_type *e)
  99. {
  100. return IDENTIFIER_HASH_VALUE (DECL_NAME (e->decl));
  101. }
  102. inline bool
  103. decl_addr_hasher::equal (const value_type *p1, const compare_type *p2)
  104. {
  105. return p1->decl == p2->decl;
  106. }
  107. struct string_hasher : typed_noop_remove<char>
  108. {
  109. typedef char value_type;
  110. typedef char compare_type;
  111. static inline hashval_t hash (const value_type *s)
  112. {
  113. return htab_hash_string (s);
  114. }
  115. static inline bool equal (const value_type *p1, const value_type *p2)
  116. {
  117. return strcmp (p1, p2) == 0;
  118. }
  119. };
  120. // A wrapper for pushdecl that doesn't let gdb have a chance to
  121. // instantiate a symbol.
  122. static void
  123. pushdecl_safe (tree decl)
  124. {
  125. void (*save) (enum c_oracle_request, tree identifier);
  126. save = c_binding_oracle;
  127. c_binding_oracle = NULL;
  128. pushdecl (decl);
  129. c_binding_oracle = save;
  130. }
  131. struct plugin_context : public cc1_plugin::connection
  132. {
  133. plugin_context (int fd);
  134. // Map decls to addresses.
  135. hash_table<decl_addr_hasher> address_map;
  136. // A collection of trees that are preserved for the GC.
  137. hash_table< pointer_hash<tree_node> > preserved;
  138. // File name cache.
  139. hash_table<string_hasher> file_names;
  140. // Perform GC marking.
  141. void mark ();
  142. // Preserve a tree during the plugin's operation.
  143. tree preserve (tree t)
  144. {
  145. tree_node **slot = preserved.find_slot (t, INSERT);
  146. *slot = t;
  147. return t;
  148. }
  149. source_location get_source_location (const char *filename,
  150. unsigned int line_number)
  151. {
  152. if (filename == NULL)
  153. return UNKNOWN_LOCATION;
  154. filename = intern_filename (filename);
  155. linemap_add (line_table, LC_ENTER, false, filename, line_number);
  156. source_location loc = linemap_line_start (line_table, line_number, 0);
  157. linemap_add (line_table, LC_LEAVE, false, NULL, 0);
  158. return loc;
  159. }
  160. private:
  161. // Add a file name to FILE_NAMES and return the canonical copy.
  162. const char *intern_filename (const char *filename)
  163. {
  164. char **slot = file_names.find_slot (filename, INSERT);
  165. if (*slot == NULL)
  166. {
  167. /* The file name must live as long as the line map, which
  168. effectively means as long as this compilation. So, we copy
  169. the string here but never free it. */
  170. *slot = xstrdup (filename);
  171. }
  172. return *slot;
  173. }
  174. };
  175. static plugin_context *current_context;
  176. plugin_context::plugin_context (int fd)
  177. : cc1_plugin::connection (fd),
  178. address_map (30),
  179. preserved (30),
  180. file_names (30)
  181. {
  182. }
  183. void
  184. plugin_context::mark ()
  185. {
  186. for (hash_table<decl_addr_hasher>::iterator it = address_map.begin ();
  187. it != address_map.end ();
  188. ++it)
  189. {
  190. ggc_mark ((*it)->decl);
  191. ggc_mark ((*it)->address);
  192. }
  193. for (hash_table< pointer_hash<tree_node> >::iterator it = preserved.begin ();
  194. it != preserved.end ();
  195. ++it)
  196. ggc_mark (&*it);
  197. }
  198. static void
  199. plugin_binding_oracle (enum c_oracle_request kind, tree identifier)
  200. {
  201. enum gcc_c_oracle_request request;
  202. gcc_assert (current_context != NULL);
  203. switch (kind)
  204. {
  205. case C_ORACLE_SYMBOL:
  206. request = GCC_C_ORACLE_SYMBOL;
  207. break;
  208. case C_ORACLE_TAG:
  209. request = GCC_C_ORACLE_TAG;
  210. break;
  211. case C_ORACLE_LABEL:
  212. request = GCC_C_ORACLE_LABEL;
  213. break;
  214. default:
  215. abort ();
  216. }
  217. int ignore;
  218. cc1_plugin::call (current_context, "binding_oracle", &ignore,
  219. request, IDENTIFIER_POINTER (identifier));
  220. }
  221. static void
  222. plugin_pragma_user_expression (cpp_reader *)
  223. {
  224. c_binding_oracle = plugin_binding_oracle;
  225. }
  226. static void
  227. plugin_init_extra_pragmas (void *, void *)
  228. {
  229. c_register_pragma ("GCC", "user_expression", plugin_pragma_user_expression);
  230. }
  231. // Maybe rewrite a decl to its address.
  232. static tree
  233. address_rewriter (tree *in, int *walk_subtrees, void *arg)
  234. {
  235. plugin_context *ctx = (plugin_context *) arg;
  236. if (!DECL_P (*in) || DECL_NAME (*in) == NULL_TREE)
  237. return NULL_TREE;
  238. decl_addr_value value;
  239. value.decl = *in;
  240. decl_addr_value *found_value = ctx->address_map.find (&value);
  241. if (found_value != NULL)
  242. {
  243. // At this point we don't need VLA sizes for gdb-supplied
  244. // variables, and having them here confuses later passes, so we
  245. // drop them.
  246. if (C_TYPE_VARIABLE_SIZE (TREE_TYPE (*in)))
  247. {
  248. TREE_TYPE (*in)
  249. = build_array_type_nelts (TREE_TYPE (TREE_TYPE (*in)), 1);
  250. DECL_SIZE (*in) = TYPE_SIZE (TREE_TYPE (*in));
  251. DECL_SIZE_UNIT (*in) = TYPE_SIZE_UNIT (TREE_TYPE (*in));
  252. }
  253. }
  254. else if (DECL_IS_BUILTIN (*in))
  255. {
  256. gcc_address address;
  257. if (!cc1_plugin::call (ctx, "address_oracle", &address,
  258. IDENTIFIER_POINTER (DECL_NAME (*in))))
  259. return NULL_TREE;
  260. if (address == 0)
  261. return NULL_TREE;
  262. // Insert the decl into the address map in case it is referenced
  263. // again.
  264. value.address = build_int_cst_type (ptr_type_node, address);
  265. decl_addr_value **slot = ctx->address_map.find_slot (&value, INSERT);
  266. gcc_assert (*slot == NULL);
  267. *slot
  268. = static_cast<decl_addr_value *> (xmalloc (sizeof (decl_addr_value)));
  269. **slot = value;
  270. found_value = *slot;
  271. }
  272. else
  273. return NULL_TREE;
  274. if (found_value->address != error_mark_node)
  275. {
  276. // We have an address for the decl, so rewrite the tree.
  277. tree ptr_type = build_pointer_type (TREE_TYPE (*in));
  278. *in = fold_build1 (INDIRECT_REF, TREE_TYPE (*in),
  279. fold_build1 (CONVERT_EXPR, ptr_type,
  280. found_value->address));
  281. }
  282. *walk_subtrees = 0;
  283. return NULL_TREE;
  284. }
  285. // When generating code for gdb, we want to be able to use absolute
  286. // addresses to refer to otherwise external objects that gdb knows
  287. // about. gdb passes in these addresses when building decls, and then
  288. // before gimplification we go through the trees, rewriting uses to
  289. // the equivalent of "*(TYPE *) ADDR".
  290. static void
  291. rewrite_decls_to_addresses (void *function_in, void *)
  292. {
  293. tree function = (tree) function_in;
  294. // Do nothing if we're not in gdb.
  295. if (current_context == NULL)
  296. return;
  297. walk_tree (&DECL_SAVED_TREE (function), address_rewriter, current_context,
  298. NULL);
  299. }
  300. gcc_decl
  301. plugin_build_decl (cc1_plugin::connection *self,
  302. const char *name,
  303. enum gcc_c_symbol_kind sym_kind,
  304. gcc_type sym_type_in,
  305. const char *substitution_name,
  306. gcc_address address,
  307. const char *filename,
  308. unsigned int line_number)
  309. {
  310. plugin_context *ctx = static_cast<plugin_context *> (self);
  311. tree identifier = get_identifier (name);
  312. enum tree_code code;
  313. tree decl;
  314. tree sym_type = convert_in (sym_type_in);
  315. switch (sym_kind)
  316. {
  317. case GCC_C_SYMBOL_FUNCTION:
  318. code = FUNCTION_DECL;
  319. break;
  320. case GCC_C_SYMBOL_VARIABLE:
  321. code = VAR_DECL;
  322. break;
  323. case GCC_C_SYMBOL_TYPEDEF:
  324. code = TYPE_DECL;
  325. break;
  326. case GCC_C_SYMBOL_LABEL:
  327. // FIXME: we aren't ready to handle labels yet.
  328. // It isn't clear how to translate them properly
  329. // and in any case a "goto" isn't likely to work.
  330. return convert_out (error_mark_node);
  331. default:
  332. abort ();
  333. }
  334. source_location loc = ctx->get_source_location (filename, line_number);
  335. decl = build_decl (loc, code, identifier, sym_type);
  336. TREE_USED (decl) = 1;
  337. TREE_ADDRESSABLE (decl) = 1;
  338. if (sym_kind != GCC_C_SYMBOL_TYPEDEF)
  339. {
  340. decl_addr_value value;
  341. value.decl = decl;
  342. if (substitution_name != NULL)
  343. {
  344. // If the translator gave us a name without a binding,
  345. // we can just substitute error_mark_node, since we know the
  346. // translator will be reporting an error anyhow.
  347. value.address
  348. = lookup_name (get_identifier (substitution_name));
  349. if (value.address == NULL_TREE)
  350. value.address = error_mark_node;
  351. }
  352. else
  353. value.address = build_int_cst_type (ptr_type_node, address);
  354. decl_addr_value **slot = ctx->address_map.find_slot (&value, INSERT);
  355. gcc_assert (*slot == NULL);
  356. *slot
  357. = static_cast<decl_addr_value *> (xmalloc (sizeof (decl_addr_value)));
  358. **slot = value;
  359. }
  360. return convert_out (ctx->preserve (decl));
  361. }
  362. int
  363. plugin_bind (cc1_plugin::connection *,
  364. gcc_decl decl_in, int is_global)
  365. {
  366. tree decl = convert_in (decl_in);
  367. c_bind (DECL_SOURCE_LOCATION (decl), decl, is_global);
  368. rest_of_decl_compilation (decl, is_global, 0);
  369. return 1;
  370. }
  371. int
  372. plugin_tagbind (cc1_plugin::connection *self,
  373. const char *name, gcc_type tagged_type,
  374. const char *filename, unsigned int line_number)
  375. {
  376. plugin_context *ctx = static_cast<plugin_context *> (self);
  377. c_pushtag (ctx->get_source_location (filename, line_number),
  378. get_identifier (name), convert_in (tagged_type));
  379. return 1;
  380. }
  381. gcc_type
  382. plugin_build_pointer_type (cc1_plugin::connection *,
  383. gcc_type base_type)
  384. {
  385. // No need to preserve a pointer type as the base type is preserved.
  386. return convert_out (build_pointer_type (convert_in (base_type)));
  387. }
  388. gcc_type
  389. plugin_build_record_type (cc1_plugin::connection *self)
  390. {
  391. plugin_context *ctx = static_cast<plugin_context *> (self);
  392. return convert_out (ctx->preserve (make_node (RECORD_TYPE)));
  393. }
  394. gcc_type
  395. plugin_build_union_type (cc1_plugin::connection *self)
  396. {
  397. plugin_context *ctx = static_cast<plugin_context *> (self);
  398. return convert_out (ctx->preserve (make_node (UNION_TYPE)));
  399. }
  400. int
  401. plugin_build_add_field (cc1_plugin::connection *,
  402. gcc_type record_or_union_type_in,
  403. const char *field_name,
  404. gcc_type field_type_in,
  405. unsigned long bitsize,
  406. unsigned long bitpos)
  407. {
  408. tree record_or_union_type = convert_in (record_or_union_type_in);
  409. tree field_type = convert_in (field_type_in);
  410. gcc_assert (TREE_CODE (record_or_union_type) == RECORD_TYPE
  411. || TREE_CODE (record_or_union_type) == UNION_TYPE);
  412. /* Note that gdb does not preserve the location of field decls, so
  413. we can't provide a decent location here. */
  414. tree decl = build_decl (BUILTINS_LOCATION, FIELD_DECL,
  415. get_identifier (field_name), field_type);
  416. DECL_FIELD_CONTEXT (decl) = record_or_union_type;
  417. if (TREE_CODE (field_type) == INTEGER_TYPE
  418. && TYPE_PRECISION (field_type) != bitsize)
  419. {
  420. DECL_BIT_FIELD_TYPE (decl) = field_type;
  421. TREE_TYPE (decl)
  422. = c_build_bitfield_integer_type (bitsize, TYPE_UNSIGNED (field_type));
  423. }
  424. DECL_MODE (decl) = TYPE_MODE (TREE_TYPE (decl));
  425. // There's no way to recover this from DWARF.
  426. SET_DECL_OFFSET_ALIGN (decl, TYPE_PRECISION (pointer_sized_int_node));
  427. tree pos = bitsize_int (bitpos);
  428. pos_from_bit (&DECL_FIELD_OFFSET (decl), &DECL_FIELD_BIT_OFFSET (decl),
  429. DECL_OFFSET_ALIGN (decl), pos);
  430. DECL_SIZE (decl) = bitsize_int (bitsize);
  431. DECL_SIZE_UNIT (decl) = size_int ((bitsize + BITS_PER_UNIT - 1)
  432. / BITS_PER_UNIT);
  433. DECL_CHAIN (decl) = TYPE_FIELDS (record_or_union_type);
  434. TYPE_FIELDS (record_or_union_type) = decl;
  435. return 1;
  436. }
  437. int
  438. plugin_finish_record_or_union (cc1_plugin::connection *,
  439. gcc_type record_or_union_type_in,
  440. unsigned long size_in_bytes)
  441. {
  442. tree record_or_union_type = convert_in (record_or_union_type_in);
  443. gcc_assert (TREE_CODE (record_or_union_type) == RECORD_TYPE
  444. || TREE_CODE (record_or_union_type) == UNION_TYPE);
  445. /* We built the field list in reverse order, so fix it now. */
  446. TYPE_FIELDS (record_or_union_type)
  447. = nreverse (TYPE_FIELDS (record_or_union_type));
  448. if (TREE_CODE (record_or_union_type) == UNION_TYPE)
  449. {
  450. /* Unions can just be handled by the generic code. */
  451. layout_type (record_or_union_type);
  452. }
  453. else
  454. {
  455. // FIXME there's no way to get this from DWARF,
  456. // or even, it seems, a particularly good way to deduce it.
  457. TYPE_ALIGN (record_or_union_type)
  458. = TYPE_PRECISION (pointer_sized_int_node);
  459. TYPE_SIZE (record_or_union_type) = bitsize_int (size_in_bytes
  460. * BITS_PER_UNIT);
  461. TYPE_SIZE_UNIT (record_or_union_type) = size_int (size_in_bytes);
  462. compute_record_mode (record_or_union_type);
  463. finish_bitfield_layout (record_or_union_type);
  464. // FIXME we have no idea about TYPE_PACKED
  465. }
  466. return 1;
  467. }
  468. gcc_type
  469. plugin_build_enum_type (cc1_plugin::connection *self,
  470. gcc_type underlying_int_type_in)
  471. {
  472. tree underlying_int_type = convert_in (underlying_int_type_in);
  473. if (underlying_int_type == error_mark_node)
  474. return convert_out (error_mark_node);
  475. tree result = make_node (ENUMERAL_TYPE);
  476. TYPE_PRECISION (result) = TYPE_PRECISION (underlying_int_type);
  477. TYPE_UNSIGNED (result) = TYPE_UNSIGNED (underlying_int_type);
  478. plugin_context *ctx = static_cast<plugin_context *> (self);
  479. return convert_out (ctx->preserve (result));
  480. }
  481. int
  482. plugin_build_add_enum_constant (cc1_plugin::connection *,
  483. gcc_type enum_type_in,
  484. const char *name,
  485. unsigned long value)
  486. {
  487. tree cst, decl, cons;
  488. tree enum_type = convert_in (enum_type_in);
  489. gcc_assert (TREE_CODE (enum_type) == ENUMERAL_TYPE);
  490. cst = build_int_cst (enum_type, value);
  491. /* Note that gdb does not preserve the location of enum constants,
  492. so we can't provide a decent location here. */
  493. decl = build_decl (BUILTINS_LOCATION, CONST_DECL,
  494. get_identifier (name), enum_type);
  495. DECL_INITIAL (decl) = cst;
  496. pushdecl_safe (decl);
  497. cons = tree_cons (DECL_NAME (decl), cst, TYPE_VALUES (enum_type));
  498. TYPE_VALUES (enum_type) = cons;
  499. return 1;
  500. }
  501. int
  502. plugin_finish_enum_type (cc1_plugin::connection *,
  503. gcc_type enum_type_in)
  504. {
  505. tree enum_type = convert_in (enum_type_in);
  506. tree minnode, maxnode, iter;
  507. iter = TYPE_VALUES (enum_type);
  508. minnode = maxnode = TREE_VALUE (iter);
  509. for (iter = TREE_CHAIN (iter);
  510. iter != NULL_TREE;
  511. iter = TREE_CHAIN (iter))
  512. {
  513. tree value = TREE_VALUE (iter);
  514. if (tree_int_cst_lt (maxnode, value))
  515. maxnode = value;
  516. if (tree_int_cst_lt (value, minnode))
  517. minnode = value;
  518. }
  519. TYPE_MIN_VALUE (enum_type) = minnode;
  520. TYPE_MAX_VALUE (enum_type) = maxnode;
  521. layout_type (enum_type);
  522. return 1;
  523. }
  524. gcc_type
  525. plugin_build_function_type (cc1_plugin::connection *self,
  526. gcc_type return_type_in,
  527. const struct gcc_type_array *argument_types_in,
  528. int is_varargs)
  529. {
  530. tree *argument_types;
  531. tree return_type = convert_in (return_type_in);
  532. tree result;
  533. argument_types = new tree[argument_types_in->n_elements];
  534. for (int i = 0; i < argument_types_in->n_elements; ++i)
  535. argument_types[i] = convert_in (argument_types_in->elements[i]);
  536. if (is_varargs)
  537. result = build_varargs_function_type_array (return_type,
  538. argument_types_in->n_elements,
  539. argument_types);
  540. else
  541. result = build_function_type_array (return_type,
  542. argument_types_in->n_elements,
  543. argument_types);
  544. delete[] argument_types;
  545. plugin_context *ctx = static_cast<plugin_context *> (self);
  546. return convert_out (ctx->preserve (result));
  547. }
  548. gcc_type
  549. plugin_int_type (cc1_plugin::connection *self,
  550. int is_unsigned, unsigned long size_in_bytes)
  551. {
  552. tree result = c_common_type_for_size (BITS_PER_UNIT * size_in_bytes,
  553. is_unsigned);
  554. if (result == NULL_TREE)
  555. result = error_mark_node;
  556. else
  557. {
  558. plugin_context *ctx = static_cast<plugin_context *> (self);
  559. ctx->preserve (result);
  560. }
  561. return convert_out (result);
  562. }
  563. gcc_type
  564. plugin_float_type (cc1_plugin::connection *,
  565. unsigned long size_in_bytes)
  566. {
  567. if (BITS_PER_UNIT * size_in_bytes == TYPE_PRECISION (float_type_node))
  568. return convert_out (float_type_node);
  569. if (BITS_PER_UNIT * size_in_bytes == TYPE_PRECISION (double_type_node))
  570. return convert_out (double_type_node);
  571. if (BITS_PER_UNIT * size_in_bytes == TYPE_PRECISION (long_double_type_node))
  572. return convert_out (long_double_type_node);
  573. return convert_out (error_mark_node);
  574. }
  575. gcc_type
  576. plugin_void_type (cc1_plugin::connection *)
  577. {
  578. return convert_out (void_type_node);
  579. }
  580. gcc_type
  581. plugin_bool_type (cc1_plugin::connection *)
  582. {
  583. return convert_out (boolean_type_node);
  584. }
  585. gcc_type
  586. plugin_build_array_type (cc1_plugin::connection *self,
  587. gcc_type element_type_in, int num_elements)
  588. {
  589. tree element_type = convert_in (element_type_in);
  590. tree result;
  591. if (num_elements == -1)
  592. result = build_array_type (element_type, NULL_TREE);
  593. else
  594. result = build_array_type_nelts (element_type, num_elements);
  595. plugin_context *ctx = static_cast<plugin_context *> (self);
  596. return convert_out (ctx->preserve (result));
  597. }
  598. gcc_type
  599. plugin_build_vla_array_type (cc1_plugin::connection *self,
  600. gcc_type element_type_in,
  601. const char *upper_bound_name)
  602. {
  603. tree element_type = convert_in (element_type_in);
  604. tree upper_bound = lookup_name (get_identifier (upper_bound_name));
  605. tree range = build_index_type (upper_bound);
  606. tree result = build_array_type (element_type, range);
  607. C_TYPE_VARIABLE_SIZE (result) = 1;
  608. plugin_context *ctx = static_cast<plugin_context *> (self);
  609. return convert_out (ctx->preserve (result));
  610. }
  611. gcc_type
  612. plugin_build_qualified_type (cc1_plugin::connection *,
  613. gcc_type unqualified_type_in,
  614. enum gcc_qualifiers qualifiers)
  615. {
  616. tree unqualified_type = convert_in (unqualified_type_in);
  617. int quals = 0;
  618. if ((qualifiers & GCC_QUALIFIER_CONST) != 0)
  619. quals |= TYPE_QUAL_CONST;
  620. if ((qualifiers & GCC_QUALIFIER_VOLATILE) != 0)
  621. quals |= TYPE_QUAL_VOLATILE;
  622. if ((qualifiers & GCC_QUALIFIER_RESTRICT) != 0)
  623. quals |= TYPE_QUAL_RESTRICT;
  624. return convert_out (build_qualified_type (unqualified_type, quals));
  625. }
  626. gcc_type
  627. plugin_build_complex_type (cc1_plugin::connection *self,
  628. gcc_type base_type)
  629. {
  630. plugin_context *ctx = static_cast<plugin_context *> (self);
  631. return convert_out (ctx->preserve (build_complex_type (convert_in (base_type))));
  632. }
  633. gcc_type
  634. plugin_build_vector_type (cc1_plugin::connection *self,
  635. gcc_type base_type, int nunits)
  636. {
  637. plugin_context *ctx = static_cast<plugin_context *> (self);
  638. return convert_out (ctx->preserve (build_vector_type (convert_in (base_type),
  639. nunits)));
  640. }
  641. int
  642. plugin_build_constant (cc1_plugin::connection *self, gcc_type type_in,
  643. const char *name, unsigned long value,
  644. const char *filename, unsigned int line_number)
  645. {
  646. plugin_context *ctx = static_cast<plugin_context *> (self);
  647. tree cst, decl;
  648. tree type = convert_in (type_in);
  649. cst = build_int_cst (type, value);
  650. decl = build_decl (ctx->get_source_location (filename, line_number),
  651. CONST_DECL, get_identifier (name), type);
  652. DECL_INITIAL (decl) = cst;
  653. pushdecl_safe (decl);
  654. return 1;
  655. }
  656. gcc_type
  657. plugin_error (cc1_plugin::connection *,
  658. const char *message)
  659. {
  660. error ("%s", message);
  661. return convert_out (error_mark_node);
  662. }
  663. // Perform GC marking.
  664. static void
  665. gc_mark (void *, void *)
  666. {
  667. if (current_context != NULL)
  668. current_context->mark ();
  669. }
  670. #ifdef __GNUC__
  671. #pragma GCC visibility push(default)
  672. #endif
  673. int
  674. plugin_init (struct plugin_name_args *plugin_info,
  675. struct plugin_gcc_version *)
  676. {
  677. long fd = -1;
  678. for (int i = 0; i < plugin_info->argc; ++i)
  679. {
  680. if (strcmp (plugin_info->argv[i].key, "fd") == 0)
  681. {
  682. char *tail;
  683. errno = 0;
  684. fd = strtol (plugin_info->argv[i].value, &tail, 0);
  685. if (*tail != '\0' || errno != 0)
  686. fatal_error (input_location,
  687. "%s: invalid file descriptor argument to plugin",
  688. plugin_info->base_name);
  689. break;
  690. }
  691. }
  692. if (fd == -1)
  693. fatal_error (input_location,
  694. "%s: required plugin argument %<fd%> is missing",
  695. plugin_info->base_name);
  696. current_context = new plugin_context (fd);
  697. // Handshake.
  698. cc1_plugin::protocol_int version;
  699. if (!current_context->require ('H')
  700. || ! ::cc1_plugin::unmarshall (current_context, &version))
  701. fatal_error (input_location,
  702. "%s: handshake failed", plugin_info->base_name);
  703. if (version != GCC_C_FE_VERSION_0)
  704. fatal_error (input_location,
  705. "%s: unknown version in handshake", plugin_info->base_name);
  706. register_callback (plugin_info->base_name, PLUGIN_PRAGMAS,
  707. plugin_init_extra_pragmas, NULL);
  708. register_callback (plugin_info->base_name, PLUGIN_PRE_GENERICIZE,
  709. rewrite_decls_to_addresses, NULL);
  710. register_callback (plugin_info->base_name, PLUGIN_GGC_MARKING,
  711. gc_mark, NULL);
  712. lang_hooks.print_error_function = plugin_print_error_function;
  713. #define GCC_METHOD0(R, N) \
  714. { \
  715. cc1_plugin::callback_ftype *fun \
  716. = cc1_plugin::callback<R, plugin_ ## N>; \
  717. current_context->add_callback (# N, fun); \
  718. }
  719. #define GCC_METHOD1(R, N, A) \
  720. { \
  721. cc1_plugin::callback_ftype *fun \
  722. = cc1_plugin::callback<R, A, plugin_ ## N>; \
  723. current_context->add_callback (# N, fun); \
  724. }
  725. #define GCC_METHOD2(R, N, A, B) \
  726. { \
  727. cc1_plugin::callback_ftype *fun \
  728. = cc1_plugin::callback<R, A, B, plugin_ ## N>; \
  729. current_context->add_callback (# N, fun); \
  730. }
  731. #define GCC_METHOD3(R, N, A, B, C) \
  732. { \
  733. cc1_plugin::callback_ftype *fun \
  734. = cc1_plugin::callback<R, A, B, C, plugin_ ## N>; \
  735. current_context->add_callback (# N, fun); \
  736. }
  737. #define GCC_METHOD4(R, N, A, B, C, D) \
  738. { \
  739. cc1_plugin::callback_ftype *fun \
  740. = cc1_plugin::callback<R, A, B, C, D, \
  741. plugin_ ## N>; \
  742. current_context->add_callback (# N, fun); \
  743. }
  744. #define GCC_METHOD5(R, N, A, B, C, D, E) \
  745. { \
  746. cc1_plugin::callback_ftype *fun \
  747. = cc1_plugin::callback<R, A, B, C, D, E, \
  748. plugin_ ## N>; \
  749. current_context->add_callback (# N, fun); \
  750. }
  751. #define GCC_METHOD7(R, N, A, B, C, D, E, F, G) \
  752. { \
  753. cc1_plugin::callback_ftype *fun \
  754. = cc1_plugin::callback<R, A, B, C, D, E, F, G, \
  755. plugin_ ## N>; \
  756. current_context->add_callback (# N, fun); \
  757. }
  758. #include "gcc-c-fe.def"
  759. #undef GCC_METHOD0
  760. #undef GCC_METHOD1
  761. #undef GCC_METHOD2
  762. #undef GCC_METHOD3
  763. #undef GCC_METHOD4
  764. #undef GCC_METHOD5
  765. #undef GCC_METHOD7
  766. return 0;
  767. }