Branch data Line data Source code
1 : : // go-gcc.cc -- Go frontend to gcc IR.
2 : : // Copyright (C) 2011-2025 Free Software Foundation, Inc.
3 : : // Contributed by Ian Lance Taylor, Google.
4 : :
5 : : // This file is part of GCC.
6 : :
7 : : // GCC is free software; you can redistribute it and/or modify it under
8 : : // the terms of the GNU General Public License as published by the Free
9 : : // Software Foundation; either version 3, or (at your option) any later
10 : : // version.
11 : :
12 : : // GCC is distributed in the hope that it will be useful, but WITHOUT ANY
13 : : // WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 : : // FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
15 : : // for more details.
16 : :
17 : : // You should have received a copy of the GNU General Public License
18 : : // along with GCC; see the file COPYING3. If not see
19 : : // <http://www.gnu.org/licenses/>.
20 : :
21 : : #include "go-system.h"
22 : :
23 : : // This has to be included outside of extern "C", so we have to
24 : : // include it here before tree.h includes it later.
25 : : #include <gmp.h>
26 : :
27 : : #include "tree.h"
28 : : #include "opts.h"
29 : : #include "fold-const.h"
30 : : #include "stringpool.h"
31 : : #include "stor-layout.h"
32 : : #include "varasm.h"
33 : : #include "tree-iterator.h"
34 : : #include "tm.h"
35 : : #include "function.h"
36 : : #include "cgraph.h"
37 : : #include "convert.h"
38 : : #include "gimple-expr.h"
39 : : #include "gimplify.h"
40 : : #include "langhooks.h"
41 : : #include "toplev.h"
42 : : #include "output.h"
43 : : #include "realmpfr.h"
44 : : #include "builtins.h"
45 : :
46 : : #include "go-c.h"
47 : : #include "go-gcc.h"
48 : :
49 : : #include "gogo.h"
50 : : #include "backend.h"
51 : :
52 : : // A class wrapping a tree.
53 : :
54 : : class Gcc_tree
55 : : {
56 : : public:
57 : 72636831 : Gcc_tree(tree t)
58 : 72636831 : : t_(t)
59 : : { }
60 : :
61 : : tree
62 : 136755601 : get_tree() const
63 : 586919 : { return this->t_; }
64 : :
65 : : void
66 : 2 : set_tree(tree t)
67 : 2 : { this->t_ = t; }
68 : :
69 : : private:
70 : : tree t_;
71 : : };
72 : :
73 : : // In gcc, types, expressions, and statements are all trees.
74 : : class Btype : public Gcc_tree
75 : : {
76 : : public:
77 : 6230507 : Btype(tree t)
78 : 6230507 : : Gcc_tree(t)
79 : : { }
80 : : };
81 : :
82 : : class Bexpression : public Gcc_tree
83 : : {
84 : : public:
85 : 52306897 : Bexpression(tree t)
86 : 52306897 : : Gcc_tree(t)
87 : : { }
88 : : };
89 : :
90 : : class Bstatement : public Gcc_tree
91 : : {
92 : : public:
93 : 9799155 : Bstatement(tree t)
94 : 9799155 : : Gcc_tree(t)
95 : : { }
96 : : };
97 : :
98 : : class Bfunction : public Gcc_tree
99 : : {
100 : : public:
101 : 1247600 : Bfunction(tree t)
102 : 1247600 : : Gcc_tree(t)
103 : : { }
104 : : };
105 : :
106 : : class Bblock : public Gcc_tree
107 : : {
108 : : public:
109 : 2859508 : Bblock(tree t)
110 : 2859508 : : Gcc_tree(t)
111 : : { }
112 : : };
113 : :
114 : : class Blabel : public Gcc_tree
115 : : {
116 : : public:
117 : 193164 : Blabel(tree t)
118 : 193164 : : Gcc_tree(t)
119 : : { }
120 : : };
121 : :
122 : : // Bvariable is a bit more complicated, because of zero-sized types.
123 : : // The GNU linker does not permit dynamic variables with zero size.
124 : : // When we see such a variable, we generate a version of the type with
125 : : // non-zero size. However, when referring to the global variable, we
126 : : // want an expression of zero size; otherwise, if, say, the global
127 : : // variable is passed to a function, we will be passing a
128 : : // non-zero-sized value to a zero-sized value, which can lead to a
129 : : // miscompilation.
130 : :
131 : : class Bvariable
132 : : {
133 : : public:
134 : 5122333 : Bvariable(tree t)
135 : 5122333 : : t_(t), orig_type_(NULL)
136 : : { }
137 : :
138 : 34340 : Bvariable(tree t, tree orig_type)
139 : 34340 : : t_(t), orig_type_(orig_type)
140 : : { }
141 : :
142 : : // Get the tree for use as an expression.
143 : : tree
144 : : get_tree(Location) const;
145 : :
146 : : // Get the actual decl;
147 : : tree
148 : 3264967 : get_decl() const
149 : 3264967 : { return this->t_; }
150 : :
151 : : private:
152 : : tree t_;
153 : : tree orig_type_;
154 : : };
155 : :
156 : : // Get the tree of a variable for use as an expression. If this is a
157 : : // zero-sized global, create an expression that refers to the decl but
158 : : // has zero size.
159 : : tree
160 : 12124179 : Bvariable::get_tree(Location location) const
161 : : {
162 : 12124179 : if (this->orig_type_ == NULL
163 : 474762 : || this->t_ == error_mark_node
164 : 12598941 : || TREE_TYPE(this->t_) == this->orig_type_)
165 : 12122023 : return this->t_;
166 : : // Return *(orig_type*)&decl. */
167 : 2156 : tree t = build_fold_addr_expr_loc(location.gcc_location(), this->t_);
168 : 2156 : t = fold_build1_loc(location.gcc_location(), NOP_EXPR,
169 : 2156 : build_pointer_type(this->orig_type_), t);
170 : 2156 : return build_fold_indirect_ref_loc(location.gcc_location(), t);
171 : : }
172 : :
173 : : // This file implements the interface between the Go frontend proper
174 : : // and the gcc IR. This implements specific instantiations of
175 : : // abstract classes defined by the Go frontend proper. The Go
176 : : // frontend proper class methods of these classes to generate the
177 : : // backend representation.
178 : :
179 : : class Gcc_backend : public Backend
180 : : {
181 : : public:
182 : : Gcc_backend();
183 : :
184 : : // Types.
185 : :
186 : : Btype*
187 : 172 : error_type()
188 : 344 : { return this->make_type(error_mark_node); }
189 : :
190 : : Btype*
191 : 7816 : void_type()
192 : 15632 : { return this->make_type(void_type_node); }
193 : :
194 : : Btype*
195 : 6768 : bool_type()
196 : 13536 : { return this->make_type(boolean_type_node); }
197 : :
198 : : Btype*
199 : : integer_type(bool, int);
200 : :
201 : : Btype*
202 : : float_type(int);
203 : :
204 : : Btype*
205 : : complex_type(int);
206 : :
207 : : Btype*
208 : : pointer_type(Btype*);
209 : :
210 : : Btype*
211 : : function_type(const Btyped_identifier&,
212 : : const std::vector<Btyped_identifier>&,
213 : : const std::vector<Btyped_identifier>&,
214 : : Btype*,
215 : : const Location);
216 : :
217 : : Btype*
218 : : struct_type(const std::vector<Btyped_identifier>&);
219 : :
220 : : Btype*
221 : : array_type(Btype*, Bexpression*);
222 : :
223 : : Btype*
224 : : placeholder_pointer_type(const std::string&, Location, bool);
225 : :
226 : : bool
227 : : set_placeholder_pointer_type(Btype*, Btype*);
228 : :
229 : : bool
230 : : set_placeholder_function_type(Btype*, Btype*);
231 : :
232 : : Btype*
233 : : placeholder_struct_type(const std::string&, Location);
234 : :
235 : : bool
236 : : set_placeholder_struct_type(Btype* placeholder,
237 : : const std::vector<Btyped_identifier>&);
238 : :
239 : : Btype*
240 : : placeholder_array_type(const std::string&, Location);
241 : :
242 : : bool
243 : : set_placeholder_array_type(Btype*, Btype*, Bexpression*);
244 : :
245 : : Btype*
246 : : named_type(const std::string&, Btype*, Location);
247 : :
248 : : Btype*
249 : : circular_pointer_type(Btype*, bool);
250 : :
251 : : bool
252 : : is_circular_pointer_type(Btype*);
253 : :
254 : : int64_t
255 : : type_size(Btype*);
256 : :
257 : : int64_t
258 : : type_alignment(Btype*);
259 : :
260 : : int64_t
261 : : type_field_alignment(Btype*);
262 : :
263 : : int64_t
264 : : type_field_offset(Btype*, size_t index);
265 : :
266 : : // Expressions.
267 : :
268 : : Bexpression*
269 : : zero_expression(Btype*);
270 : :
271 : : Bexpression*
272 : 3834 : error_expression()
273 : 7668 : { return this->make_expression(error_mark_node); }
274 : :
275 : : Bexpression*
276 : 1242344 : nil_pointer_expression()
277 : 2484688 : { return this->make_expression(null_pointer_node); }
278 : :
279 : : Bexpression*
280 : : var_expression(Bvariable* var, Location);
281 : :
282 : : Bexpression*
283 : : indirect_expression(Btype*, Bexpression* expr, bool known_valid, Location);
284 : :
285 : : Bexpression*
286 : : named_constant_expression(Btype* btype, const std::string& name,
287 : : Bexpression* val, Location);
288 : :
289 : : Bexpression*
290 : : integer_constant_expression(Btype* btype, mpz_t val);
291 : :
292 : : Bexpression*
293 : : float_constant_expression(Btype* btype, mpfr_t val);
294 : :
295 : : Bexpression*
296 : : complex_constant_expression(Btype* btype, mpc_t val);
297 : :
298 : : Bexpression*
299 : : string_constant_expression(const std::string& val);
300 : :
301 : : Bexpression*
302 : : boolean_constant_expression(bool val);
303 : :
304 : : Bexpression*
305 : : real_part_expression(Bexpression* bcomplex, Location);
306 : :
307 : : Bexpression*
308 : : imag_part_expression(Bexpression* bcomplex, Location);
309 : :
310 : : Bexpression*
311 : : complex_expression(Bexpression* breal, Bexpression* bimag, Location);
312 : :
313 : : Bexpression*
314 : : convert_expression(Btype* type, Bexpression* expr, Location);
315 : :
316 : : Bexpression*
317 : : function_code_expression(Bfunction*, Location);
318 : :
319 : : Bexpression*
320 : : address_expression(Bexpression*, Location);
321 : :
322 : : Bexpression*
323 : : struct_field_expression(Bexpression*, size_t, Location);
324 : :
325 : : Bexpression*
326 : : compound_expression(Bstatement*, Bexpression*, Location);
327 : :
328 : : Bexpression*
329 : : conditional_expression(Bfunction*, Btype*, Bexpression*, Bexpression*,
330 : : Bexpression*, Location);
331 : :
332 : : Bexpression*
333 : : unary_expression(Operator, Bexpression*, Location);
334 : :
335 : : Bexpression*
336 : : binary_expression(Operator, Bexpression*, Bexpression*, Location);
337 : :
338 : : Bexpression*
339 : : constructor_expression(Btype*, const std::vector<Bexpression*>&, Location);
340 : :
341 : : Bexpression*
342 : : array_constructor_expression(Btype*, const std::vector<unsigned long>&,
343 : : const std::vector<Bexpression*>&, Location);
344 : :
345 : : Bexpression*
346 : : pointer_offset_expression(Bexpression* base, Bexpression* offset, Location);
347 : :
348 : : Bexpression*
349 : : array_index_expression(Bexpression* array, Bexpression* index, Location);
350 : :
351 : : Bexpression*
352 : : call_expression(Bfunction* caller, Bexpression* fn,
353 : : const std::vector<Bexpression*>& args,
354 : : Bexpression* static_chain, Location);
355 : :
356 : : // Statements.
357 : :
358 : : Bstatement*
359 : 786 : error_statement()
360 : 1572 : { return this->make_statement(error_mark_node); }
361 : :
362 : : Bstatement*
363 : : expression_statement(Bfunction*, Bexpression*);
364 : :
365 : : Bstatement*
366 : : init_statement(Bfunction*, Bvariable* var, Bexpression* init);
367 : :
368 : : Bstatement*
369 : : assignment_statement(Bfunction*, Bexpression* lhs, Bexpression* rhs,
370 : : Location);
371 : :
372 : : Bstatement*
373 : : return_statement(Bfunction*, const std::vector<Bexpression*>&,
374 : : Location);
375 : :
376 : : Bstatement*
377 : : if_statement(Bfunction*, Bexpression* condition, Bblock* then_block,
378 : : Bblock* else_block, Location);
379 : :
380 : : Bstatement*
381 : : switch_statement(Bfunction* function, Bexpression* value,
382 : : const std::vector<std::vector<Bexpression*> >& cases,
383 : : const std::vector<Bstatement*>& statements,
384 : : Location);
385 : :
386 : : Bstatement*
387 : : compound_statement(Bstatement*, Bstatement*);
388 : :
389 : : Bstatement*
390 : : statement_list(const std::vector<Bstatement*>&);
391 : :
392 : : Bstatement*
393 : : exception_handler_statement(Bstatement* bstat, Bstatement* except_stmt,
394 : : Bstatement* finally_stmt, Location);
395 : :
396 : : // Blocks.
397 : :
398 : : Bblock*
399 : : block(Bfunction*, Bblock*, const std::vector<Bvariable*>&,
400 : : Location, Location);
401 : :
402 : : void
403 : : block_add_statements(Bblock*, const std::vector<Bstatement*>&);
404 : :
405 : : Bstatement*
406 : : block_statement(Bblock*);
407 : :
408 : : // Variables.
409 : :
410 : : Bvariable*
411 : 176 : error_variable()
412 : 176 : { return new Bvariable(error_mark_node); }
413 : :
414 : : Bvariable*
415 : : global_variable(const std::string& var_name,
416 : : const std::string& asm_name,
417 : : Btype* btype,
418 : : unsigned int flags,
419 : : Location location);
420 : :
421 : : void
422 : : global_variable_set_init(Bvariable*, Bexpression*);
423 : :
424 : : Bvariable*
425 : : local_variable(Bfunction*, const std::string&, Btype*, Bvariable*,
426 : : unsigned int, Location);
427 : :
428 : : Bvariable*
429 : : parameter_variable(Bfunction*, const std::string&, Btype*, unsigned int,
430 : : Location);
431 : :
432 : : Bvariable*
433 : : static_chain_variable(Bfunction*, const std::string&, Btype*, unsigned int,
434 : : Location);
435 : :
436 : : Bvariable*
437 : : temporary_variable(Bfunction*, Bblock*, Btype*, Bexpression*, unsigned int,
438 : : Location, Bstatement**);
439 : :
440 : : Bvariable*
441 : : implicit_variable(const std::string&, const std::string&, Btype*,
442 : : unsigned int, int64_t);
443 : :
444 : : void
445 : : implicit_variable_set_init(Bvariable*, const std::string&, Btype*,
446 : : unsigned int, Bexpression*);
447 : :
448 : : Bvariable*
449 : : implicit_variable_reference(const std::string&, const std::string&, Btype*);
450 : :
451 : : Bvariable*
452 : : immutable_struct(const std::string&, const std::string&,
453 : : unsigned int, Btype*, Location);
454 : :
455 : : void
456 : : immutable_struct_set_init(Bvariable*, const std::string&, unsigned int,
457 : : Btype*, Location, Bexpression*);
458 : :
459 : : Bvariable*
460 : : immutable_struct_reference(const std::string&, const std::string&,
461 : : Btype*, Location);
462 : :
463 : : // Labels.
464 : :
465 : : Blabel*
466 : : label(Bfunction*, const std::string& name, Location);
467 : :
468 : : Bstatement*
469 : : label_definition_statement(Blabel*);
470 : :
471 : : Bstatement*
472 : : goto_statement(Blabel*, Location);
473 : :
474 : : Bexpression*
475 : : label_address(Blabel*, Location);
476 : :
477 : : // Functions.
478 : :
479 : : Bfunction*
480 : 14 : error_function()
481 : 28 : { return this->make_function(error_mark_node); }
482 : :
483 : : Bfunction*
484 : : function(Btype* fntype, const std::string& name, const std::string& asm_name,
485 : : unsigned int flags, Location);
486 : :
487 : : Bstatement*
488 : : function_defer_statement(Bfunction* function, Bexpression* undefer,
489 : : Bexpression* defer, Location);
490 : :
491 : : bool
492 : : function_set_parameters(Bfunction* function, const std::vector<Bvariable*>&);
493 : :
494 : : bool
495 : : function_set_body(Bfunction* function, Bstatement* code_stmt);
496 : :
497 : : Bfunction*
498 : : lookup_builtin(const std::string&);
499 : :
500 : : void
501 : : write_global_definitions(const std::vector<Btype*>&,
502 : : const std::vector<Bexpression*>&,
503 : : const std::vector<Bfunction*>&,
504 : : const std::vector<Bvariable*>&);
505 : :
506 : : void
507 : : write_export_data(const char* bytes, unsigned int size);
508 : :
509 : :
510 : : private:
511 : : // Make a Bexpression from a tree.
512 : : Bexpression*
513 : 52306897 : make_expression(tree t)
514 : 1246178 : { return new Bexpression(t); }
515 : :
516 : : // Make a Bstatement from a tree.
517 : : Bstatement*
518 : 9799155 : make_statement(tree t)
519 : 786 : { return new Bstatement(t); }
520 : :
521 : : // Make a Btype from a tree.
522 : : Btype*
523 : 6230507 : make_type(tree t)
524 : 14756 : { return new Btype(t); }
525 : :
526 : : Bfunction*
527 : 636516 : make_function(tree t)
528 : 14 : { return new Bfunction(t); }
529 : :
530 : : Btype*
531 : : fill_in_struct(Btype*, const std::vector<Btyped_identifier>&);
532 : :
533 : : Btype*
534 : : fill_in_array(Btype*, Btype*, Bexpression*);
535 : :
536 : : tree
537 : : non_zero_size_type(tree);
538 : :
539 : : tree
540 : : convert_tree(tree, tree, Location);
541 : :
542 : : private:
543 : : static const int builtin_cold = 1 << 0;
544 : : static const int builtin_const = 1 << 1;
545 : : static const int builtin_leaf = 1 << 2;
546 : : static const int builtin_nonnull = 1 << 3;
547 : : static const int builtin_noreturn = 1 << 4;
548 : : static const int builtin_nothrow = 1 << 5;
549 : : static const int builtin_novops = 1 << 6;
550 : : static const int builtin_pure = 1 << 7;
551 : :
552 : : void
553 : : define_builtin(built_in_function bcode, const char* name, const char* libname,
554 : : tree fntype, int flags);
555 : :
556 : : void
557 : : set_attributes(tree decl, int flags);
558 : :
559 : : // A mapping of the GCC built-ins exposed to GCCGo.
560 : : std::map<std::string, Bfunction*> builtin_functions_;
561 : : };
562 : :
563 : : // A helper function to create a GCC identifier from a C++ string.
564 : :
565 : : static inline tree
566 : 12618150 : get_identifier_from_string(const std::string& str)
567 : : {
568 : 12618150 : return get_identifier_with_length(str.data(), str.length());
569 : : }
570 : :
571 : : // Define the built-in functions that are exposed to GCCGo.
572 : :
573 : 4646 : Gcc_backend::Gcc_backend()
574 : : {
575 : : /* We need to define the fetch_and_add functions, since we use them
576 : : for ++ and --. */
577 : 4646 : tree t = this->integer_type(true, BITS_PER_UNIT)->get_tree();
578 : 4646 : tree p = build_pointer_type(build_qualified_type(t, TYPE_QUAL_VOLATILE));
579 : 4646 : this->define_builtin(BUILT_IN_SYNC_ADD_AND_FETCH_1, "__sync_fetch_and_add_1",
580 : : NULL, build_function_type_list(t, p, t, NULL_TREE),
581 : : builtin_leaf);
582 : :
583 : 4646 : t = this->integer_type(true, BITS_PER_UNIT * 2)->get_tree();
584 : 4646 : p = build_pointer_type(build_qualified_type(t, TYPE_QUAL_VOLATILE));
585 : 4646 : this->define_builtin(BUILT_IN_SYNC_ADD_AND_FETCH_2, "__sync_fetch_and_add_2",
586 : : NULL, build_function_type_list(t, p, t, NULL_TREE),
587 : : builtin_leaf);
588 : :
589 : 4646 : t = this->integer_type(true, BITS_PER_UNIT * 4)->get_tree();
590 : 4646 : p = build_pointer_type(build_qualified_type(t, TYPE_QUAL_VOLATILE));
591 : 4646 : this->define_builtin(BUILT_IN_SYNC_ADD_AND_FETCH_4, "__sync_fetch_and_add_4",
592 : : NULL, build_function_type_list(t, p, t, NULL_TREE),
593 : : builtin_leaf);
594 : :
595 : 4646 : t = this->integer_type(true, BITS_PER_UNIT * 8)->get_tree();
596 : 4646 : p = build_pointer_type(build_qualified_type(t, TYPE_QUAL_VOLATILE));
597 : 4646 : this->define_builtin(BUILT_IN_SYNC_ADD_AND_FETCH_8, "__sync_fetch_and_add_8",
598 : : NULL, build_function_type_list(t, p, t, NULL_TREE),
599 : : builtin_leaf);
600 : :
601 : : // We use __builtin_expect for magic import functions.
602 : 4646 : this->define_builtin(BUILT_IN_EXPECT, "__builtin_expect", NULL,
603 : : build_function_type_list(long_integer_type_node,
604 : : long_integer_type_node,
605 : : long_integer_type_node,
606 : : NULL_TREE),
607 : : builtin_const | builtin_nothrow | builtin_leaf);
608 : :
609 : : // We use __builtin_memcmp for struct comparisons.
610 : 4646 : this->define_builtin(BUILT_IN_MEMCMP, "__builtin_memcmp", "memcmp",
611 : : build_function_type_list(integer_type_node,
612 : : const_ptr_type_node,
613 : : const_ptr_type_node,
614 : : size_type_node,
615 : : NULL_TREE),
616 : : builtin_pure | builtin_nothrow | builtin_nonnull);
617 : :
618 : : // We use __builtin_memmove for copying data.
619 : 4646 : this->define_builtin(BUILT_IN_MEMMOVE, "__builtin_memmove", "memmove",
620 : : build_function_type_list(void_type_node,
621 : : ptr_type_node,
622 : : const_ptr_type_node,
623 : : size_type_node,
624 : : NULL_TREE),
625 : : builtin_nothrow | builtin_nonnull);
626 : :
627 : : // We use __builtin_memset for zeroing data.
628 : 4646 : this->define_builtin(BUILT_IN_MEMSET, "__builtin_memset", "memset",
629 : : build_function_type_list(void_type_node,
630 : : ptr_type_node,
631 : : integer_type_node,
632 : : size_type_node,
633 : : NULL_TREE),
634 : : builtin_nothrow | builtin_nonnull);
635 : :
636 : : // Used by runtime/internal/sys and math/bits.
637 : 4646 : this->define_builtin(BUILT_IN_CTZ, "__builtin_ctz", "ctz",
638 : : build_function_type_list(integer_type_node,
639 : : unsigned_type_node,
640 : : NULL_TREE),
641 : : builtin_const | builtin_nothrow | builtin_leaf);
642 : 4646 : this->define_builtin(BUILT_IN_CTZL, "__builtin_ctzl", "ctzl",
643 : : build_function_type_list(integer_type_node,
644 : : long_unsigned_type_node,
645 : : NULL_TREE),
646 : : builtin_const | builtin_nothrow | builtin_leaf);
647 : 4646 : this->define_builtin(BUILT_IN_CTZLL, "__builtin_ctzll", "ctzll",
648 : : build_function_type_list(integer_type_node,
649 : : long_long_unsigned_type_node,
650 : : NULL_TREE),
651 : : builtin_const | builtin_nothrow | builtin_leaf);
652 : 4646 : this->define_builtin(BUILT_IN_CLZ, "__builtin_clz", "clz",
653 : : build_function_type_list(integer_type_node,
654 : : unsigned_type_node,
655 : : NULL_TREE),
656 : : builtin_const | builtin_nothrow | builtin_leaf);
657 : 4646 : this->define_builtin(BUILT_IN_CLZL, "__builtin_clzl", "clzl",
658 : : build_function_type_list(integer_type_node,
659 : : long_unsigned_type_node,
660 : : NULL_TREE),
661 : : builtin_const | builtin_nothrow | builtin_leaf);
662 : 4646 : this->define_builtin(BUILT_IN_CLZLL, "__builtin_clzll", "clzll",
663 : : build_function_type_list(integer_type_node,
664 : : long_long_unsigned_type_node,
665 : : NULL_TREE),
666 : : builtin_const | builtin_nothrow | builtin_leaf);
667 : 4646 : this->define_builtin(BUILT_IN_POPCOUNT, "__builtin_popcount", "popcount",
668 : : build_function_type_list(integer_type_node,
669 : : unsigned_type_node,
670 : : NULL_TREE),
671 : : builtin_const | builtin_nothrow | builtin_leaf);
672 : 4646 : this->define_builtin(BUILT_IN_POPCOUNTLL, "__builtin_popcountll", "popcountll",
673 : : build_function_type_list(integer_type_node,
674 : : long_long_unsigned_type_node,
675 : : NULL_TREE),
676 : : builtin_const | builtin_nothrow | builtin_leaf);
677 : 4646 : this->define_builtin(BUILT_IN_BSWAP16, "__builtin_bswap16", "bswap16",
678 : : build_function_type_list(uint16_type_node,
679 : : uint16_type_node,
680 : : NULL_TREE),
681 : : builtin_const | builtin_nothrow | builtin_leaf);
682 : 4646 : this->define_builtin(BUILT_IN_BSWAP32, "__builtin_bswap32", "bswap32",
683 : : build_function_type_list(uint32_type_node,
684 : : uint32_type_node,
685 : : NULL_TREE),
686 : : builtin_const | builtin_nothrow | builtin_leaf);
687 : 4646 : this->define_builtin(BUILT_IN_BSWAP64, "__builtin_bswap64", "bswap64",
688 : : build_function_type_list(uint64_type_node,
689 : : uint64_type_node,
690 : : NULL_TREE),
691 : : builtin_const | builtin_nothrow | builtin_leaf);
692 : :
693 : : // We provide some functions for the math library.
694 : 4646 : tree math_function_type = build_function_type_list(double_type_node,
695 : : double_type_node,
696 : : NULL_TREE);
697 : 4646 : tree math_function_type_long =
698 : 4646 : build_function_type_list(long_double_type_node, long_double_type_node,
699 : : NULL_TREE);
700 : 4646 : tree math_function_type_two = build_function_type_list(double_type_node,
701 : : double_type_node,
702 : : double_type_node,
703 : : NULL_TREE);
704 : 4646 : tree math_function_type_long_two =
705 : 4646 : build_function_type_list(long_double_type_node, long_double_type_node,
706 : : long_double_type_node, NULL_TREE);
707 : 4646 : this->define_builtin(BUILT_IN_ACOS, "__builtin_acos", "acos",
708 : : math_function_type, builtin_const);
709 : 4646 : this->define_builtin(BUILT_IN_ACOSL, "__builtin_acosl", "acosl",
710 : : math_function_type_long, builtin_const);
711 : 4646 : this->define_builtin(BUILT_IN_ASIN, "__builtin_asin", "asin",
712 : : math_function_type, builtin_const);
713 : 4646 : this->define_builtin(BUILT_IN_ASINL, "__builtin_asinl", "asinl",
714 : : math_function_type_long, builtin_const);
715 : 4646 : this->define_builtin(BUILT_IN_ATAN, "__builtin_atan", "atan",
716 : : math_function_type, builtin_const);
717 : 4646 : this->define_builtin(BUILT_IN_ATANL, "__builtin_atanl", "atanl",
718 : : math_function_type_long, builtin_const);
719 : 4646 : this->define_builtin(BUILT_IN_ATAN2, "__builtin_atan2", "atan2",
720 : : math_function_type_two, builtin_const);
721 : 4646 : this->define_builtin(BUILT_IN_ATAN2L, "__builtin_atan2l", "atan2l",
722 : : math_function_type_long_two, builtin_const);
723 : 4646 : this->define_builtin(BUILT_IN_CEIL, "__builtin_ceil", "ceil",
724 : : math_function_type, builtin_const);
725 : 4646 : this->define_builtin(BUILT_IN_CEILL, "__builtin_ceill", "ceill",
726 : : math_function_type_long, builtin_const);
727 : 4646 : this->define_builtin(BUILT_IN_COS, "__builtin_cos", "cos",
728 : : math_function_type, builtin_const);
729 : 4646 : this->define_builtin(BUILT_IN_COSL, "__builtin_cosl", "cosl",
730 : : math_function_type_long, builtin_const);
731 : 4646 : this->define_builtin(BUILT_IN_EXP, "__builtin_exp", "exp",
732 : : math_function_type, builtin_const);
733 : 4646 : this->define_builtin(BUILT_IN_EXPL, "__builtin_expl", "expl",
734 : : math_function_type_long, builtin_const);
735 : 4646 : this->define_builtin(BUILT_IN_EXPM1, "__builtin_expm1", "expm1",
736 : : math_function_type, builtin_const);
737 : 4646 : this->define_builtin(BUILT_IN_EXPM1L, "__builtin_expm1l", "expm1l",
738 : : math_function_type_long, builtin_const);
739 : 4646 : this->define_builtin(BUILT_IN_FABS, "__builtin_fabs", "fabs",
740 : : math_function_type, builtin_const);
741 : 4646 : this->define_builtin(BUILT_IN_FABSL, "__builtin_fabsl", "fabsl",
742 : : math_function_type_long, builtin_const);
743 : 4646 : this->define_builtin(BUILT_IN_FLOOR, "__builtin_floor", "floor",
744 : : math_function_type, builtin_const);
745 : 4646 : this->define_builtin(BUILT_IN_FLOORL, "__builtin_floorl", "floorl",
746 : : math_function_type_long, builtin_const);
747 : 4646 : this->define_builtin(BUILT_IN_FMOD, "__builtin_fmod", "fmod",
748 : : math_function_type_two, builtin_const);
749 : 4646 : this->define_builtin(BUILT_IN_FMODL, "__builtin_fmodl", "fmodl",
750 : : math_function_type_long_two, builtin_const);
751 : 4646 : this->define_builtin(BUILT_IN_LDEXP, "__builtin_ldexp", "ldexp",
752 : : build_function_type_list(double_type_node,
753 : : double_type_node,
754 : : integer_type_node,
755 : : NULL_TREE),
756 : : builtin_const);
757 : 4646 : this->define_builtin(BUILT_IN_LDEXPL, "__builtin_ldexpl", "ldexpl",
758 : : build_function_type_list(long_double_type_node,
759 : : long_double_type_node,
760 : : integer_type_node,
761 : : NULL_TREE),
762 : : builtin_const);
763 : 4646 : this->define_builtin(BUILT_IN_LOG, "__builtin_log", "log",
764 : : math_function_type, builtin_const);
765 : 4646 : this->define_builtin(BUILT_IN_LOGL, "__builtin_logl", "logl",
766 : : math_function_type_long, builtin_const);
767 : 4646 : this->define_builtin(BUILT_IN_LOG1P, "__builtin_log1p", "log1p",
768 : : math_function_type, builtin_const);
769 : 4646 : this->define_builtin(BUILT_IN_LOG1PL, "__builtin_log1pl", "log1pl",
770 : : math_function_type_long, builtin_const);
771 : 4646 : this->define_builtin(BUILT_IN_LOG10, "__builtin_log10", "log10",
772 : : math_function_type, builtin_const);
773 : 4646 : this->define_builtin(BUILT_IN_LOG10L, "__builtin_log10l", "log10l",
774 : : math_function_type_long, builtin_const);
775 : 4646 : this->define_builtin(BUILT_IN_LOG2, "__builtin_log2", "log2",
776 : : math_function_type, builtin_const);
777 : 4646 : this->define_builtin(BUILT_IN_LOG2L, "__builtin_log2l", "log2l",
778 : : math_function_type_long, builtin_const);
779 : 4646 : this->define_builtin(BUILT_IN_SIN, "__builtin_sin", "sin",
780 : : math_function_type, builtin_const);
781 : 4646 : this->define_builtin(BUILT_IN_SINL, "__builtin_sinl", "sinl",
782 : : math_function_type_long, builtin_const);
783 : 4646 : this->define_builtin(BUILT_IN_SQRT, "__builtin_sqrt", "sqrt",
784 : : math_function_type, builtin_const);
785 : 4646 : this->define_builtin(BUILT_IN_SQRTL, "__builtin_sqrtl", "sqrtl",
786 : : math_function_type_long, builtin_const);
787 : 4646 : this->define_builtin(BUILT_IN_TAN, "__builtin_tan", "tan",
788 : : math_function_type, builtin_const);
789 : 4646 : this->define_builtin(BUILT_IN_TANL, "__builtin_tanl", "tanl",
790 : : math_function_type_long, builtin_const);
791 : 4646 : this->define_builtin(BUILT_IN_TRUNC, "__builtin_trunc", "trunc",
792 : : math_function_type, builtin_const);
793 : 4646 : this->define_builtin(BUILT_IN_TRUNCL, "__builtin_truncl", "truncl",
794 : : math_function_type_long, builtin_const);
795 : :
796 : : // We use __builtin_return_address in the thunk we build for
797 : : // functions which call recover, and for runtime.getcallerpc.
798 : 4646 : t = build_function_type_list(ptr_type_node, unsigned_type_node, NULL_TREE);
799 : 4646 : this->define_builtin(BUILT_IN_RETURN_ADDRESS, "__builtin_return_address",
800 : : NULL, t, builtin_leaf);
801 : :
802 : : // The runtime calls __builtin_dwarf_cfa for runtime.getcallersp.
803 : 4646 : t = build_function_type_list(ptr_type_node, NULL_TREE);
804 : 4646 : this->define_builtin(BUILT_IN_DWARF_CFA, "__builtin_dwarf_cfa",
805 : : NULL, t, 0);
806 : :
807 : : // The runtime calls __builtin_extract_return_addr when recording
808 : : // the address to which a function returns.
809 : 4646 : this->define_builtin(BUILT_IN_EXTRACT_RETURN_ADDR,
810 : : "__builtin_extract_return_addr", NULL,
811 : : build_function_type_list(ptr_type_node,
812 : : ptr_type_node,
813 : : NULL_TREE),
814 : : builtin_leaf);
815 : :
816 : : // The compiler uses __builtin_trap for some exception handling
817 : : // cases.
818 : 4646 : this->define_builtin(BUILT_IN_TRAP, "__builtin_trap", NULL,
819 : : build_function_type(void_type_node, void_list_node),
820 : : (builtin_noreturn | builtin_nothrow | builtin_leaf
821 : : | builtin_cold));
822 : :
823 : : // The runtime uses __builtin_prefetch.
824 : 4646 : this->define_builtin(BUILT_IN_PREFETCH, "__builtin_prefetch", NULL,
825 : : build_varargs_function_type_list(void_type_node,
826 : : const_ptr_type_node,
827 : : NULL_TREE),
828 : : builtin_novops | builtin_leaf);
829 : :
830 : : // The compiler uses __builtin_unreachable for cases that cannot
831 : : // occur.
832 : 4646 : this->define_builtin(BUILT_IN_UNREACHABLE, "__builtin_unreachable", NULL,
833 : : build_function_type(void_type_node, void_list_node),
834 : : (builtin_const | builtin_noreturn | builtin_nothrow
835 : : | builtin_leaf | builtin_cold));
836 : :
837 : : // We provide some atomic functions.
838 : 4646 : t = build_function_type_list(uint32_type_node,
839 : : ptr_type_node,
840 : : integer_type_node,
841 : : NULL_TREE);
842 : 4646 : this->define_builtin(BUILT_IN_ATOMIC_LOAD_4, "__atomic_load_4", NULL,
843 : : t, builtin_leaf);
844 : :
845 : 4646 : t = build_function_type_list(uint64_type_node,
846 : : ptr_type_node,
847 : : integer_type_node,
848 : : NULL_TREE);
849 : 4646 : this->define_builtin(BUILT_IN_ATOMIC_LOAD_8, "__atomic_load_8", NULL,
850 : : t, builtin_leaf);
851 : :
852 : 4646 : t = build_function_type_list(void_type_node,
853 : : ptr_type_node,
854 : : uint32_type_node,
855 : : integer_type_node,
856 : : NULL_TREE);
857 : 4646 : this->define_builtin(BUILT_IN_ATOMIC_STORE_4, "__atomic_store_4", NULL,
858 : : t, builtin_leaf);
859 : :
860 : 4646 : t = build_function_type_list(void_type_node,
861 : : ptr_type_node,
862 : : uint64_type_node,
863 : : integer_type_node,
864 : : NULL_TREE);
865 : 4646 : this->define_builtin(BUILT_IN_ATOMIC_STORE_8, "__atomic_store_8", NULL,
866 : : t, builtin_leaf);
867 : :
868 : 4646 : t = build_function_type_list(uint32_type_node,
869 : : ptr_type_node,
870 : : uint32_type_node,
871 : : integer_type_node,
872 : : NULL_TREE);
873 : 4646 : this->define_builtin(BUILT_IN_ATOMIC_EXCHANGE_4, "__atomic_exchange_4", NULL,
874 : : t, builtin_leaf);
875 : :
876 : 4646 : t = build_function_type_list(uint64_type_node,
877 : : ptr_type_node,
878 : : uint64_type_node,
879 : : integer_type_node,
880 : : NULL_TREE);
881 : 4646 : this->define_builtin(BUILT_IN_ATOMIC_EXCHANGE_8, "__atomic_exchange_8", NULL,
882 : : t, builtin_leaf);
883 : :
884 : 4646 : t = build_function_type_list(boolean_type_node,
885 : : ptr_type_node,
886 : : ptr_type_node,
887 : : uint32_type_node,
888 : : boolean_type_node,
889 : : integer_type_node,
890 : : integer_type_node,
891 : : NULL_TREE);
892 : 4646 : this->define_builtin(BUILT_IN_ATOMIC_COMPARE_EXCHANGE_4,
893 : : "__atomic_compare_exchange_4", NULL,
894 : : t, builtin_leaf);
895 : :
896 : 4646 : t = build_function_type_list(boolean_type_node,
897 : : ptr_type_node,
898 : : ptr_type_node,
899 : : uint64_type_node,
900 : : boolean_type_node,
901 : : integer_type_node,
902 : : integer_type_node,
903 : : NULL_TREE);
904 : 4646 : this->define_builtin(BUILT_IN_ATOMIC_COMPARE_EXCHANGE_8,
905 : : "__atomic_compare_exchange_8", NULL,
906 : : t, builtin_leaf);
907 : :
908 : 4646 : t = build_function_type_list(uint32_type_node,
909 : : ptr_type_node,
910 : : uint32_type_node,
911 : : integer_type_node,
912 : : NULL_TREE);
913 : 4646 : this->define_builtin(BUILT_IN_ATOMIC_ADD_FETCH_4, "__atomic_add_fetch_4",
914 : : NULL, t, builtin_leaf);
915 : 4646 : this->define_builtin(BUILT_IN_ATOMIC_FETCH_ADD_4, "__atomic_fetch_add_4",
916 : : NULL, t, builtin_leaf);
917 : :
918 : 4646 : t = build_function_type_list(uint64_type_node,
919 : : ptr_type_node,
920 : : uint64_type_node,
921 : : integer_type_node,
922 : : NULL_TREE);
923 : 4646 : this->define_builtin(BUILT_IN_ATOMIC_ADD_FETCH_8, "__atomic_add_fetch_8",
924 : : NULL, t, builtin_leaf);
925 : 4646 : this->define_builtin(BUILT_IN_ATOMIC_FETCH_ADD_8, "__atomic_fetch_add_8",
926 : : NULL, t, builtin_leaf);
927 : :
928 : 4646 : t = build_function_type_list(unsigned_char_type_node,
929 : : ptr_type_node,
930 : : integer_type_node,
931 : : NULL_TREE);
932 : 4646 : this->define_builtin(BUILT_IN_ATOMIC_LOAD_1, "__atomic_load_1", NULL, t,
933 : : builtin_leaf);
934 : :
935 : 4646 : t = build_function_type_list(void_type_node,
936 : : ptr_type_node,
937 : : unsigned_char_type_node,
938 : : integer_type_node,
939 : : NULL_TREE);
940 : 4646 : this->define_builtin(BUILT_IN_ATOMIC_STORE_1, "__atomic_store_1", NULL,
941 : : t, builtin_leaf);
942 : :
943 : 4646 : t = build_function_type_list(unsigned_char_type_node,
944 : : ptr_type_node,
945 : : unsigned_char_type_node,
946 : : integer_type_node,
947 : : NULL_TREE);
948 : 4646 : this->define_builtin(BUILT_IN_ATOMIC_AND_FETCH_1, "__atomic_and_fetch_1", NULL,
949 : : t, builtin_leaf);
950 : 4646 : this->define_builtin(BUILT_IN_ATOMIC_FETCH_AND_1, "__atomic_fetch_and_1", NULL,
951 : : t, builtin_leaf);
952 : :
953 : 4646 : t = build_function_type_list(unsigned_char_type_node,
954 : : ptr_type_node,
955 : : unsigned_char_type_node,
956 : : integer_type_node,
957 : : NULL_TREE);
958 : 4646 : this->define_builtin(BUILT_IN_ATOMIC_OR_FETCH_1, "__atomic_or_fetch_1", NULL,
959 : : t, builtin_leaf);
960 : 4646 : this->define_builtin(BUILT_IN_ATOMIC_FETCH_OR_1, "__atomic_fetch_or_1", NULL,
961 : : t, builtin_leaf);
962 : 4646 : }
963 : :
964 : : // Get an unnamed integer type.
965 : :
966 : : Btype*
967 : 196631 : Gcc_backend::integer_type(bool is_unsigned, int bits)
968 : : {
969 : 196631 : tree type;
970 : 196631 : if (is_unsigned)
971 : : {
972 : 118691 : if (bits == INT_TYPE_SIZE)
973 : 35709 : type = unsigned_type_node;
974 : 82982 : else if (bits == CHAR_TYPE_SIZE)
975 : 32228 : type = unsigned_char_type_node;
976 : 50754 : else if (bits == SHORT_TYPE_SIZE)
977 : 10917 : type = short_unsigned_type_node;
978 : 43356 : else if (bits == LONG_TYPE_SIZE)
979 : 36318 : type = long_unsigned_type_node;
980 : 3519 : else if (bits == LONG_LONG_TYPE_SIZE)
981 : 3519 : type = long_long_unsigned_type_node;
982 : : else
983 : 0 : type = make_unsigned_type(bits);
984 : : }
985 : : else
986 : : {
987 : 77940 : if (bits == INT_TYPE_SIZE)
988 : 30426 : type = integer_type_node;
989 : 47514 : else if (bits == CHAR_TYPE_SIZE)
990 : 5905 : type = signed_char_type_node;
991 : 41609 : else if (bits == SHORT_TYPE_SIZE)
992 : 4928 : type = short_integer_type_node;
993 : 39502 : else if (bits == LONG_TYPE_SIZE)
994 : 33860 : type = long_integer_type_node;
995 : 2821 : else if (bits == LONG_LONG_TYPE_SIZE)
996 : 2821 : type = long_long_integer_type_node;
997 : : else
998 : 0 : type = make_signed_type(bits);
999 : : }
1000 : 196631 : return this->make_type(type);
1001 : : }
1002 : :
1003 : : // Get an unnamed float type.
1004 : :
1005 : : Btype*
1006 : 9827 : Gcc_backend::float_type(int bits)
1007 : : {
1008 : 9827 : tree type;
1009 : 9827 : if (bits == TYPE_PRECISION (float_type_node))
1010 : : type = float_type_node;
1011 : 5058 : else if (bits == TYPE_PRECISION (double_type_node))
1012 : : type = double_type_node;
1013 : 0 : else if (bits == TYPE_PRECISION (long_double_type_node))
1014 : : type = long_double_type_node;
1015 : : else
1016 : : {
1017 : 0 : type = make_node(REAL_TYPE);
1018 : 0 : TYPE_PRECISION(type) = bits;
1019 : 0 : layout_type(type);
1020 : : }
1021 : 9827 : return this->make_type(type);
1022 : : }
1023 : :
1024 : : // Get an unnamed complex type.
1025 : :
1026 : : Btype*
1027 : 9466 : Gcc_backend::complex_type(int bits)
1028 : : {
1029 : 9466 : tree type;
1030 : 9466 : if (bits == TYPE_PRECISION (float_type_node) * 2)
1031 : 4706 : type = complex_float_type_node;
1032 : 4760 : else if (bits == TYPE_PRECISION (double_type_node) * 2)
1033 : 4760 : type = complex_double_type_node;
1034 : 0 : else if (bits == TYPE_PRECISION (long_double_type_node) * 2)
1035 : 0 : type = complex_long_double_type_node;
1036 : : else
1037 : : {
1038 : 0 : type = make_node(REAL_TYPE);
1039 : 0 : TYPE_PRECISION(type) = bits / 2;
1040 : 0 : layout_type(type);
1041 : 0 : type = build_complex_type(type);
1042 : : }
1043 : 9466 : return this->make_type(type);
1044 : : }
1045 : :
1046 : : // Get a pointer type.
1047 : :
1048 : : Btype*
1049 : 2390286 : Gcc_backend::pointer_type(Btype* to_type)
1050 : : {
1051 : 2390286 : tree to_type_tree = to_type->get_tree();
1052 : 2390286 : if (to_type_tree == error_mark_node)
1053 : 13 : return this->error_type();
1054 : 2390273 : tree type = build_pointer_type(to_type_tree);
1055 : 2390273 : return this->make_type(type);
1056 : : }
1057 : :
1058 : : // Make a function type.
1059 : :
1060 : : Btype*
1061 : 883276 : Gcc_backend::function_type(const Btyped_identifier& receiver,
1062 : : const std::vector<Btyped_identifier>& parameters,
1063 : : const std::vector<Btyped_identifier>& results,
1064 : : Btype* result_struct,
1065 : : Location)
1066 : : {
1067 : 883276 : tree args = NULL_TREE;
1068 : 883276 : tree* pp = &args;
1069 : 883276 : if (receiver.btype != NULL)
1070 : : {
1071 : 198072 : tree t = receiver.btype->get_tree();
1072 : 198072 : if (t == error_mark_node)
1073 : 5 : return this->error_type();
1074 : 198067 : *pp = tree_cons(NULL_TREE, t, NULL_TREE);
1075 : 198067 : pp = &TREE_CHAIN(*pp);
1076 : : }
1077 : :
1078 : 883271 : for (std::vector<Btyped_identifier>::const_iterator p = parameters.begin();
1079 : 2169588 : p != parameters.end();
1080 : 1286317 : ++p)
1081 : : {
1082 : 1286325 : tree t = p->btype->get_tree();
1083 : 1286325 : if (t == error_mark_node)
1084 : 8 : return this->error_type();
1085 : 1286317 : *pp = tree_cons(NULL_TREE, t, NULL_TREE);
1086 : 1286317 : pp = &TREE_CHAIN(*pp);
1087 : : }
1088 : :
1089 : : // Varargs is handled entirely at the Go level. When converted to
1090 : : // GENERIC functions are not varargs.
1091 : 883263 : *pp = void_list_node;
1092 : :
1093 : 883263 : tree result;
1094 : 883263 : if (results.empty())
1095 : 195286 : result = void_type_node;
1096 : 687977 : else if (results.size() == 1)
1097 : 586919 : result = results.front().btype->get_tree();
1098 : : else
1099 : : {
1100 : 101058 : gcc_assert(result_struct != NULL);
1101 : 101058 : result = result_struct->get_tree();
1102 : : }
1103 : 883263 : if (result == error_mark_node)
1104 : 2 : return this->error_type();
1105 : :
1106 : : // The libffi library cannot represent a zero-sized object. To
1107 : : // avoid causing confusion on 32-bit SPARC, we treat a function that
1108 : : // returns a zero-sized value as returning void. That should do no
1109 : : // harm since there is no actual value to be returned. See
1110 : : // https://gcc.gnu.org/PR72814 for details.
1111 : 883261 : if (result != void_type_node && int_size_in_bytes(result) == 0)
1112 : 31 : result = void_type_node;
1113 : :
1114 : 883261 : tree fntype = build_function_type(result, args);
1115 : 883261 : if (fntype == error_mark_node)
1116 : 0 : return this->error_type();
1117 : :
1118 : 883261 : return this->make_type(build_pointer_type(fntype));
1119 : : }
1120 : :
1121 : : // Make a struct type.
1122 : :
1123 : : Btype*
1124 : 476318 : Gcc_backend::struct_type(const std::vector<Btyped_identifier>& fields)
1125 : : {
1126 : 476318 : return this->fill_in_struct(this->make_type(make_node(RECORD_TYPE)), fields);
1127 : : }
1128 : :
1129 : : // Fill in the fields of a struct type.
1130 : :
1131 : : Btype*
1132 : 1963883 : Gcc_backend::fill_in_struct(Btype* fill,
1133 : : const std::vector<Btyped_identifier>& fields)
1134 : : {
1135 : 1963883 : tree fill_tree = fill->get_tree();
1136 : 1963883 : tree field_trees = NULL_TREE;
1137 : 1963883 : tree* pp = &field_trees;
1138 : 1963883 : for (std::vector<Btyped_identifier>::const_iterator p = fields.begin();
1139 : 9472644 : p != fields.end();
1140 : 7508761 : ++p)
1141 : : {
1142 : 7508775 : tree name_tree = get_identifier_from_string(p->name);
1143 : 7508775 : tree type_tree = p->btype->get_tree();
1144 : 7508775 : if (type_tree == error_mark_node)
1145 : 14 : return this->error_type();
1146 : 7508761 : tree field = build_decl(p->location.gcc_location(), FIELD_DECL, name_tree,
1147 : : type_tree);
1148 : 7508761 : DECL_CONTEXT(field) = fill_tree;
1149 : 7508761 : *pp = field;
1150 : 7508761 : pp = &DECL_CHAIN(field);
1151 : : }
1152 : 1963869 : TYPE_FIELDS(fill_tree) = field_trees;
1153 : 1963869 : layout_type(fill_tree);
1154 : :
1155 : : // Because Go permits converting between named struct types and
1156 : : // equivalent struct types, for which we use VIEW_CONVERT_EXPR, and
1157 : : // because we don't try to maintain TYPE_CANONICAL for struct types,
1158 : : // we need to tell the middle-end to use structural equality.
1159 : 1963869 : SET_TYPE_STRUCTURAL_EQUALITY(fill_tree);
1160 : :
1161 : 1963869 : return fill;
1162 : : }
1163 : :
1164 : : // Make an array type.
1165 : :
1166 : : Btype*
1167 : 203506 : Gcc_backend::array_type(Btype* element_btype, Bexpression* length)
1168 : : {
1169 : 203506 : return this->fill_in_array(this->make_type(make_node(ARRAY_TYPE)),
1170 : 203506 : element_btype, length);
1171 : : }
1172 : :
1173 : : // Fill in an array type.
1174 : :
1175 : : Btype*
1176 : 215902 : Gcc_backend::fill_in_array(Btype* fill, Btype* element_type,
1177 : : Bexpression* length)
1178 : : {
1179 : 215902 : tree element_type_tree = element_type->get_tree();
1180 : 215902 : tree length_tree = length->get_tree();
1181 : 215902 : if (element_type_tree == error_mark_node || length_tree == error_mark_node)
1182 : 2 : return this->error_type();
1183 : :
1184 : 215900 : gcc_assert(TYPE_SIZE(element_type_tree) != NULL_TREE);
1185 : :
1186 : 215900 : length_tree = fold_convert(sizetype, length_tree);
1187 : :
1188 : : // build_index_type takes the maximum index, which is one less than
1189 : : // the length.
1190 : 215900 : tree index_type_tree = build_index_type(fold_build2(MINUS_EXPR, sizetype,
1191 : : length_tree,
1192 : : size_one_node));
1193 : :
1194 : 215900 : tree fill_tree = fill->get_tree();
1195 : 215900 : TREE_TYPE(fill_tree) = element_type_tree;
1196 : 215900 : TYPE_DOMAIN(fill_tree) = index_type_tree;
1197 : 215900 : TYPE_ADDR_SPACE(fill_tree) = TYPE_ADDR_SPACE(element_type_tree);
1198 : 215900 : layout_type(fill_tree);
1199 : :
1200 : 215900 : if (TYPE_STRUCTURAL_EQUALITY_P(element_type_tree))
1201 : 73209 : SET_TYPE_STRUCTURAL_EQUALITY(fill_tree);
1202 : 142691 : else if (TYPE_CANONICAL(element_type_tree) != element_type_tree
1203 : 142691 : || TYPE_CANONICAL(index_type_tree) != index_type_tree)
1204 : 32054 : TYPE_CANONICAL(fill_tree) =
1205 : 32054 : build_array_type(TYPE_CANONICAL(element_type_tree),
1206 : 32054 : TYPE_CANONICAL(index_type_tree));
1207 : :
1208 : : return fill;
1209 : : }
1210 : :
1211 : : // Create a placeholder for a pointer type.
1212 : :
1213 : : Btype*
1214 : 332783 : Gcc_backend::placeholder_pointer_type(const std::string& name,
1215 : : Location location, bool)
1216 : : {
1217 : 332783 : tree ret = build_distinct_type_copy(ptr_type_node);
1218 : 332783 : if (!name.empty())
1219 : : {
1220 : 9524 : tree decl = build_decl(location.gcc_location(), TYPE_DECL,
1221 : : get_identifier_from_string(name),
1222 : : ret);
1223 : 9524 : TYPE_NAME(ret) = decl;
1224 : : }
1225 : 332783 : return this->make_type(ret);
1226 : : }
1227 : :
1228 : : // Set the real target type for a placeholder pointer type.
1229 : :
1230 : : bool
1231 : 312212 : Gcc_backend::set_placeholder_pointer_type(Btype* placeholder,
1232 : : Btype* to_type)
1233 : : {
1234 : 312212 : tree pt = placeholder->get_tree();
1235 : 312212 : if (pt == error_mark_node)
1236 : : return false;
1237 : 312212 : gcc_assert(TREE_CODE(pt) == POINTER_TYPE);
1238 : 312212 : tree tt = to_type->get_tree();
1239 : 312212 : if (tt == error_mark_node)
1240 : : {
1241 : 2 : placeholder->set_tree(error_mark_node);
1242 : 2 : return false;
1243 : : }
1244 : 312210 : gcc_assert(TREE_CODE(tt) == POINTER_TYPE);
1245 : 312210 : TREE_TYPE(pt) = TREE_TYPE(tt);
1246 : 312210 : TYPE_CANONICAL(pt) = TYPE_CANONICAL(tt);
1247 : 312210 : if (TYPE_NAME(pt) != NULL_TREE)
1248 : : {
1249 : : // Build the data structure gcc wants to see for a typedef.
1250 : 4817 : tree copy = build_variant_type_copy(pt);
1251 : 4817 : TYPE_NAME(copy) = NULL_TREE;
1252 : 4817 : DECL_ORIGINAL_TYPE(TYPE_NAME(pt)) = copy;
1253 : : }
1254 : : return true;
1255 : : }
1256 : :
1257 : : // Set the real values for a placeholder function type.
1258 : :
1259 : : bool
1260 : 0 : Gcc_backend::set_placeholder_function_type(Btype* placeholder, Btype* ft)
1261 : : {
1262 : 0 : return this->set_placeholder_pointer_type(placeholder, ft);
1263 : : }
1264 : :
1265 : : // Create a placeholder for a struct type.
1266 : :
1267 : : Btype*
1268 : 747865 : Gcc_backend::placeholder_struct_type(const std::string& name,
1269 : : Location location)
1270 : : {
1271 : 747865 : tree ret = make_node(RECORD_TYPE);
1272 : 747865 : if (!name.empty())
1273 : : {
1274 : 739700 : tree decl = build_decl(location.gcc_location(), TYPE_DECL,
1275 : : get_identifier_from_string(name),
1276 : : ret);
1277 : 739700 : TYPE_NAME(ret) = decl;
1278 : :
1279 : : // The struct type that eventually replaces this placeholder will require
1280 : : // structural equality. The placeholder must too, so that the requirement
1281 : : // for structural equality propagates to references that are constructed
1282 : : // before the replacement occurs.
1283 : 739700 : SET_TYPE_STRUCTURAL_EQUALITY(ret);
1284 : : }
1285 : 747865 : return this->make_type(ret);
1286 : : }
1287 : :
1288 : : // Fill in the fields of a placeholder struct type.
1289 : :
1290 : : bool
1291 : 747865 : Gcc_backend::set_placeholder_struct_type(
1292 : : Btype* placeholder,
1293 : : const std::vector<Btyped_identifier>& fields)
1294 : : {
1295 : 747865 : tree t = placeholder->get_tree();
1296 : 747865 : gcc_assert(TREE_CODE(t) == RECORD_TYPE && TYPE_FIELDS(t) == NULL_TREE);
1297 : 747865 : Btype* r = this->fill_in_struct(placeholder, fields);
1298 : :
1299 : 747865 : if (TYPE_NAME(t) != NULL_TREE)
1300 : : {
1301 : : // Build the data structure gcc wants to see for a typedef.
1302 : 739700 : tree copy = build_distinct_type_copy(t);
1303 : 739700 : TYPE_NAME(copy) = NULL_TREE;
1304 : 739700 : DECL_ORIGINAL_TYPE(TYPE_NAME(t)) = copy;
1305 : 739700 : TYPE_SIZE(copy) = NULL_TREE;
1306 : 739700 : Btype* bc = this->make_type(copy);
1307 : 739700 : this->fill_in_struct(bc, fields);
1308 : 739700 : delete bc;
1309 : : }
1310 : :
1311 : 747865 : return r->get_tree() != error_mark_node;
1312 : : }
1313 : :
1314 : : // Create a placeholder for an array type.
1315 : :
1316 : : Btype*
1317 : 12396 : Gcc_backend::placeholder_array_type(const std::string& name,
1318 : : Location location)
1319 : : {
1320 : 12396 : tree ret = make_node(ARRAY_TYPE);
1321 : 12396 : tree decl = build_decl(location.gcc_location(), TYPE_DECL,
1322 : : get_identifier_from_string(name),
1323 : : ret);
1324 : 12396 : TYPE_NAME(ret) = decl;
1325 : 12396 : return this->make_type(ret);
1326 : : }
1327 : :
1328 : : // Fill in the fields of a placeholder array type.
1329 : :
1330 : : bool
1331 : 12396 : Gcc_backend::set_placeholder_array_type(Btype* placeholder,
1332 : : Btype* element_btype,
1333 : : Bexpression* length)
1334 : : {
1335 : 12396 : tree t = placeholder->get_tree();
1336 : 12396 : gcc_assert(TREE_CODE(t) == ARRAY_TYPE && TREE_TYPE(t) == NULL_TREE);
1337 : 12396 : Btype* r = this->fill_in_array(placeholder, element_btype, length);
1338 : :
1339 : : // Build the data structure gcc wants to see for a typedef.
1340 : 12396 : tree copy = build_distinct_type_copy(t);
1341 : 12396 : TYPE_NAME(copy) = NULL_TREE;
1342 : 12396 : DECL_ORIGINAL_TYPE(TYPE_NAME(t)) = copy;
1343 : :
1344 : 12396 : return r->get_tree() != error_mark_node;
1345 : : }
1346 : :
1347 : : // Return a named version of a type.
1348 : :
1349 : : Btype*
1350 : 213676 : Gcc_backend::named_type(const std::string& name, Btype* btype,
1351 : : Location location)
1352 : : {
1353 : 213676 : tree type = btype->get_tree();
1354 : 213676 : if (type == error_mark_node)
1355 : 0 : return this->error_type();
1356 : :
1357 : : // The middle-end expects a basic type to have a name. In Go every
1358 : : // basic type will have a name. The first time we see a basic type,
1359 : : // give it whatever Go name we have at this point.
1360 : 213676 : if (TYPE_NAME(type) == NULL_TREE
1361 : 81833 : && location.gcc_location() == BUILTINS_LOCATION
1362 : 213676 : && (TREE_CODE(type) == INTEGER_TYPE
1363 : 73667 : || TREE_CODE(type) == REAL_TYPE
1364 : : || TREE_CODE(type) == COMPLEX_TYPE
1365 : : || TREE_CODE(type) == BOOLEAN_TYPE))
1366 : : {
1367 : 60398 : tree decl = build_decl(BUILTINS_LOCATION, TYPE_DECL,
1368 : : get_identifier_from_string(name),
1369 : : type);
1370 : 60398 : TYPE_NAME(type) = decl;
1371 : 60398 : return this->make_type(type);
1372 : : }
1373 : :
1374 : 153278 : tree copy = build_variant_type_copy(type);
1375 : 153278 : tree decl = build_decl(location.gcc_location(), TYPE_DECL,
1376 : : get_identifier_from_string(name),
1377 : : copy);
1378 : 153278 : DECL_ORIGINAL_TYPE(decl) = type;
1379 : 153278 : TYPE_NAME(copy) = decl;
1380 : 153278 : return this->make_type(copy);
1381 : : }
1382 : :
1383 : : // Return a pointer type used as a marker for a circular type.
1384 : :
1385 : : Btype*
1386 : 49 : Gcc_backend::circular_pointer_type(Btype*, bool)
1387 : : {
1388 : 49 : return this->make_type(ptr_type_node);
1389 : : }
1390 : :
1391 : : // Return whether we might be looking at a circular type.
1392 : :
1393 : : bool
1394 : 540879 : Gcc_backend::is_circular_pointer_type(Btype* btype)
1395 : : {
1396 : 540879 : return btype->get_tree() == ptr_type_node;
1397 : : }
1398 : :
1399 : : // Return the size of a type.
1400 : :
1401 : : int64_t
1402 : 26475268 : Gcc_backend::type_size(Btype* btype)
1403 : : {
1404 : 26475268 : tree t = btype->get_tree();
1405 : 26475268 : if (t == error_mark_node)
1406 : : return 1;
1407 : 26475258 : if (t == void_type_node)
1408 : : return 0;
1409 : 26475258 : t = TYPE_SIZE_UNIT(t);
1410 : 26475258 : gcc_assert(tree_fits_uhwi_p (t));
1411 : 26475258 : unsigned HOST_WIDE_INT val_wide = TREE_INT_CST_LOW(t);
1412 : 26475258 : int64_t ret = static_cast<int64_t>(val_wide);
1413 : 26475258 : if (ret < 0 || static_cast<unsigned HOST_WIDE_INT>(ret) != val_wide)
1414 : : return -1;
1415 : : return ret;
1416 : : }
1417 : :
1418 : : // Return the alignment of a type.
1419 : :
1420 : : int64_t
1421 : 4549899 : Gcc_backend::type_alignment(Btype* btype)
1422 : : {
1423 : 4549899 : tree t = btype->get_tree();
1424 : 4549899 : if (t == error_mark_node)
1425 : : return 1;
1426 : 4549897 : return TYPE_ALIGN_UNIT(t);
1427 : : }
1428 : :
1429 : : // Return the alignment of a struct field of type BTYPE.
1430 : :
1431 : : int64_t
1432 : 1186550 : Gcc_backend::type_field_alignment(Btype* btype)
1433 : : {
1434 : 1186550 : tree t = btype->get_tree();
1435 : 1186550 : if (t == error_mark_node)
1436 : : return 1;
1437 : 1186550 : return go_field_alignment(t);
1438 : : }
1439 : :
1440 : : // Return the offset of a field in a struct.
1441 : :
1442 : : int64_t
1443 : 126961 : Gcc_backend::type_field_offset(Btype* btype, size_t index)
1444 : : {
1445 : 126961 : tree struct_tree = btype->get_tree();
1446 : 126961 : if (struct_tree == error_mark_node)
1447 : : return 0;
1448 : 126961 : gcc_assert(TREE_CODE(struct_tree) == RECORD_TYPE);
1449 : 126961 : tree field = TYPE_FIELDS(struct_tree);
1450 : 584482 : for (; index > 0; --index)
1451 : : {
1452 : 457521 : field = DECL_CHAIN(field);
1453 : 457521 : gcc_assert(field != NULL_TREE);
1454 : : }
1455 : 126961 : HOST_WIDE_INT offset_wide = int_byte_position(field);
1456 : 126961 : int64_t ret = static_cast<int64_t>(offset_wide);
1457 : 126961 : gcc_assert(ret == offset_wide);
1458 : 126961 : return ret;
1459 : : }
1460 : :
1461 : : // Return the zero value for a type.
1462 : :
1463 : : Bexpression*
1464 : 465400 : Gcc_backend::zero_expression(Btype* btype)
1465 : : {
1466 : 465400 : tree t = btype->get_tree();
1467 : 465400 : tree ret;
1468 : 465400 : if (t == error_mark_node)
1469 : : ret = error_mark_node;
1470 : : else
1471 : 465393 : ret = build_zero_cst(t);
1472 : 465400 : return this->make_expression(ret);
1473 : : }
1474 : :
1475 : : // An expression that references a variable.
1476 : :
1477 : : Bexpression*
1478 : 12124179 : Gcc_backend::var_expression(Bvariable* var, Location location)
1479 : : {
1480 : 12124179 : tree ret = var->get_tree(location);
1481 : 12124179 : if (ret == error_mark_node)
1482 : 42 : return this->error_expression();
1483 : 12124137 : return this->make_expression(ret);
1484 : : }
1485 : :
1486 : : // An expression that indirectly references an expression.
1487 : :
1488 : : Bexpression*
1489 : 1469462 : Gcc_backend::indirect_expression(Btype* btype, Bexpression* expr,
1490 : : bool known_valid, Location location)
1491 : : {
1492 : 1469462 : tree expr_tree = expr->get_tree();
1493 : 1469462 : tree type_tree = btype->get_tree();
1494 : 1469462 : if (expr_tree == error_mark_node || type_tree == error_mark_node)
1495 : 7 : return this->error_expression();
1496 : :
1497 : : // If the type of EXPR is a recursive pointer type, then we
1498 : : // need to insert a cast before indirecting.
1499 : 1469455 : tree target_type_tree = TREE_TYPE(TREE_TYPE(expr_tree));
1500 : 1469455 : if (VOID_TYPE_P(target_type_tree))
1501 : 547 : expr_tree = fold_convert_loc(location.gcc_location(),
1502 : : build_pointer_type(type_tree), expr_tree);
1503 : :
1504 : 1469455 : tree ret = build_fold_indirect_ref_loc(location.gcc_location(),
1505 : : expr_tree);
1506 : 1469455 : if (known_valid)
1507 : 271220 : TREE_THIS_NOTRAP(ret) = 1;
1508 : 1469455 : return this->make_expression(ret);
1509 : : }
1510 : :
1511 : : // Return an expression that declares a constant named NAME with the
1512 : : // constant value VAL in BTYPE.
1513 : :
1514 : : Bexpression*
1515 : 23399 : Gcc_backend::named_constant_expression(Btype* btype, const std::string& name,
1516 : : Bexpression* val, Location location)
1517 : : {
1518 : 23399 : tree type_tree = btype->get_tree();
1519 : 23399 : tree const_val = val->get_tree();
1520 : 23399 : if (type_tree == error_mark_node || const_val == error_mark_node)
1521 : 13 : return this->error_expression();
1522 : :
1523 : 23386 : tree name_tree = get_identifier_from_string(name);
1524 : 23386 : tree decl = build_decl(location.gcc_location(), CONST_DECL, name_tree,
1525 : : type_tree);
1526 : 23386 : DECL_INITIAL(decl) = const_val;
1527 : 23386 : TREE_CONSTANT(decl) = 1;
1528 : 23386 : TREE_READONLY(decl) = 1;
1529 : :
1530 : 23386 : go_preserve_from_gc(decl);
1531 : 23386 : return this->make_expression(decl);
1532 : : }
1533 : :
1534 : : // Return a typed value as a constant integer.
1535 : :
1536 : : Bexpression*
1537 : 7286166 : Gcc_backend::integer_constant_expression(Btype* btype, mpz_t val)
1538 : : {
1539 : 7286166 : tree t = btype->get_tree();
1540 : 7286166 : if (t == error_mark_node)
1541 : 0 : return this->error_expression();
1542 : :
1543 : 7286166 : tree ret = double_int_to_tree(t, mpz_get_double_int(t, val, true));
1544 : 7286166 : return this->make_expression(ret);
1545 : : }
1546 : :
1547 : : // Return a typed value as a constant floating-point number.
1548 : :
1549 : : Bexpression*
1550 : 33424 : Gcc_backend::float_constant_expression(Btype* btype, mpfr_t val)
1551 : : {
1552 : 33424 : tree t = btype->get_tree();
1553 : 33424 : tree ret;
1554 : 33424 : if (t == error_mark_node)
1555 : 0 : return this->error_expression();
1556 : :
1557 : 33424 : REAL_VALUE_TYPE r1;
1558 : 33424 : real_from_mpfr(&r1, val, t, GMP_RNDN);
1559 : 33424 : REAL_VALUE_TYPE r2;
1560 : 33424 : real_convert(&r2, TYPE_MODE(t), &r1);
1561 : 33424 : ret = build_real(t, r2);
1562 : 33424 : return this->make_expression(ret);
1563 : : }
1564 : :
1565 : : // Return a typed real and imaginary value as a constant complex number.
1566 : :
1567 : : Bexpression*
1568 : 2944 : Gcc_backend::complex_constant_expression(Btype* btype, mpc_t val)
1569 : : {
1570 : 2944 : tree t = btype->get_tree();
1571 : 2944 : tree ret;
1572 : 2944 : if (t == error_mark_node)
1573 : 0 : return this->error_expression();
1574 : :
1575 : 2944 : REAL_VALUE_TYPE r1;
1576 : 2944 : real_from_mpfr(&r1, mpc_realref(val), TREE_TYPE(t), GMP_RNDN);
1577 : 2944 : REAL_VALUE_TYPE r2;
1578 : 2944 : real_convert(&r2, TYPE_MODE(TREE_TYPE(t)), &r1);
1579 : :
1580 : 2944 : REAL_VALUE_TYPE r3;
1581 : 2944 : real_from_mpfr(&r3, mpc_imagref(val), TREE_TYPE(t), GMP_RNDN);
1582 : 2944 : REAL_VALUE_TYPE r4;
1583 : 2944 : real_convert(&r4, TYPE_MODE(TREE_TYPE(t)), &r3);
1584 : :
1585 : 2944 : ret = build_complex(t, build_real(TREE_TYPE(t), r2),
1586 : 2944 : build_real(TREE_TYPE(t), r4));
1587 : 2944 : return this->make_expression(ret);
1588 : : }
1589 : :
1590 : : // Make a constant string expression.
1591 : :
1592 : : Bexpression*
1593 : 985973 : Gcc_backend::string_constant_expression(const std::string& val)
1594 : : {
1595 : 985973 : tree index_type = build_index_type(size_int(val.length()));
1596 : 985973 : tree const_char_type = build_qualified_type(unsigned_char_type_node,
1597 : : TYPE_QUAL_CONST);
1598 : 985973 : tree string_type = build_array_type(const_char_type, index_type);
1599 : 985973 : TYPE_STRING_FLAG(string_type) = 1;
1600 : 985973 : tree string_val = build_string(val.length(), val.data());
1601 : 985973 : TREE_TYPE(string_val) = string_type;
1602 : :
1603 : 985973 : return this->make_expression(string_val);
1604 : : }
1605 : :
1606 : : // Make a constant boolean expression.
1607 : :
1608 : : Bexpression*
1609 : 652912 : Gcc_backend::boolean_constant_expression(bool val)
1610 : : {
1611 : 652912 : tree bool_cst = val ? boolean_true_node : boolean_false_node;
1612 : 652912 : return this->make_expression(bool_cst);
1613 : : }
1614 : :
1615 : : // Return the real part of a complex expression.
1616 : :
1617 : : Bexpression*
1618 : 460 : Gcc_backend::real_part_expression(Bexpression* bcomplex, Location location)
1619 : : {
1620 : 460 : tree complex_tree = bcomplex->get_tree();
1621 : 460 : if (complex_tree == error_mark_node)
1622 : 0 : return this->error_expression();
1623 : 460 : gcc_assert(COMPLEX_FLOAT_TYPE_P(TREE_TYPE(complex_tree)));
1624 : 460 : tree ret = fold_build1_loc(location.gcc_location(), REALPART_EXPR,
1625 : 460 : TREE_TYPE(TREE_TYPE(complex_tree)),
1626 : : complex_tree);
1627 : 460 : return this->make_expression(ret);
1628 : : }
1629 : :
1630 : : // Return the imaginary part of a complex expression.
1631 : :
1632 : : Bexpression*
1633 : 526 : Gcc_backend::imag_part_expression(Bexpression* bcomplex, Location location)
1634 : : {
1635 : 526 : tree complex_tree = bcomplex->get_tree();
1636 : 526 : if (complex_tree == error_mark_node)
1637 : 0 : return this->error_expression();
1638 : 526 : gcc_assert(COMPLEX_FLOAT_TYPE_P(TREE_TYPE(complex_tree)));
1639 : 526 : tree ret = fold_build1_loc(location.gcc_location(), IMAGPART_EXPR,
1640 : 526 : TREE_TYPE(TREE_TYPE(complex_tree)),
1641 : : complex_tree);
1642 : 526 : return this->make_expression(ret);
1643 : : }
1644 : :
1645 : : // Make a complex expression given its real and imaginary parts.
1646 : :
1647 : : Bexpression*
1648 : 12165 : Gcc_backend::complex_expression(Bexpression* breal, Bexpression* bimag,
1649 : : Location location)
1650 : : {
1651 : 12165 : tree real_tree = breal->get_tree();
1652 : 12165 : tree imag_tree = bimag->get_tree();
1653 : 12165 : if (real_tree == error_mark_node || imag_tree == error_mark_node)
1654 : 0 : return this->error_expression();
1655 : 12165 : gcc_assert(TYPE_MAIN_VARIANT(TREE_TYPE(real_tree))
1656 : : == TYPE_MAIN_VARIANT(TREE_TYPE(imag_tree)));
1657 : 12165 : gcc_assert(SCALAR_FLOAT_TYPE_P(TREE_TYPE(real_tree)));
1658 : 12165 : tree ret = fold_build2_loc(location.gcc_location(), COMPLEX_EXPR,
1659 : 12165 : build_complex_type(TREE_TYPE(real_tree)),
1660 : : real_tree, imag_tree);
1661 : 12165 : return this->make_expression(ret);
1662 : : }
1663 : :
1664 : : // An expression that converts an expression to a different type.
1665 : :
1666 : : Bexpression*
1667 : 9620269 : Gcc_backend::convert_expression(Btype* type, Bexpression* expr,
1668 : : Location location)
1669 : : {
1670 : 9620269 : tree type_tree = type->get_tree();
1671 : 9620269 : tree expr_tree = expr->get_tree();
1672 : 9620269 : if (type_tree == error_mark_node
1673 : 9620262 : || expr_tree == error_mark_node
1674 : 19240503 : || TREE_TYPE(expr_tree) == error_mark_node)
1675 : 35 : return this->error_expression();
1676 : :
1677 : 9620234 : tree ret;
1678 : 9620234 : if (this->type_size(type) == 0
1679 : 9620234 : || TREE_TYPE(expr_tree) == void_type_node)
1680 : : {
1681 : : // Do not convert zero-sized types.
1682 : : ret = expr_tree;
1683 : : }
1684 : 9618983 : else if (TREE_CODE(type_tree) == INTEGER_TYPE)
1685 : 2371996 : ret = fold(convert_to_integer(type_tree, expr_tree));
1686 : 7246987 : else if (TREE_CODE(type_tree) == REAL_TYPE)
1687 : 32302 : ret = fold(convert_to_real(type_tree, expr_tree));
1688 : 7214685 : else if (TREE_CODE(type_tree) == COMPLEX_TYPE)
1689 : 1447 : ret = fold(convert_to_complex(type_tree, expr_tree));
1690 : 7213238 : else if (TREE_CODE(type_tree) == POINTER_TYPE
1691 : 7213238 : && TREE_CODE(TREE_TYPE(expr_tree)) == INTEGER_TYPE)
1692 : 1578 : ret = fold(convert_to_pointer(type_tree, expr_tree));
1693 : 7211660 : else if (TREE_CODE(type_tree) == RECORD_TYPE
1694 : 7211660 : || TREE_CODE(type_tree) == ARRAY_TYPE)
1695 : 925398 : ret = fold_build1_loc(location.gcc_location(), VIEW_CONVERT_EXPR,
1696 : : type_tree, expr_tree);
1697 : : else
1698 : 6286262 : ret = fold_convert_loc(location.gcc_location(), type_tree, expr_tree);
1699 : :
1700 : 9620234 : return this->make_expression(ret);
1701 : : }
1702 : :
1703 : : // Get the address of a function.
1704 : :
1705 : : Bexpression*
1706 : 2174660 : Gcc_backend::function_code_expression(Bfunction* bfunc, Location location)
1707 : : {
1708 : 2174660 : tree func = bfunc->get_tree();
1709 : 2174660 : if (func == error_mark_node)
1710 : 3 : return this->error_expression();
1711 : :
1712 : 2174657 : tree ret = build_fold_addr_expr_loc(location.gcc_location(), func);
1713 : 2174657 : return this->make_expression(ret);
1714 : : }
1715 : :
1716 : : // Get the address of an expression.
1717 : :
1718 : : Bexpression*
1719 : 5031000 : Gcc_backend::address_expression(Bexpression* bexpr, Location location)
1720 : : {
1721 : 5031000 : tree expr = bexpr->get_tree();
1722 : 5031000 : if (expr == error_mark_node)
1723 : 14 : return this->error_expression();
1724 : :
1725 : 5030986 : tree ret = build_fold_addr_expr_loc(location.gcc_location(), expr);
1726 : 5030986 : return this->make_expression(ret);
1727 : : }
1728 : :
1729 : : // Return an expression for the field at INDEX in BSTRUCT.
1730 : :
1731 : : Bexpression*
1732 : 2430837 : Gcc_backend::struct_field_expression(Bexpression* bstruct, size_t index,
1733 : : Location location)
1734 : : {
1735 : 2430837 : tree struct_tree = bstruct->get_tree();
1736 : 2430837 : if (struct_tree == error_mark_node
1737 : 2430837 : || TREE_TYPE(struct_tree) == error_mark_node)
1738 : 3 : return this->error_expression();
1739 : :
1740 : : // A function call that returns a zero-sized object will have been
1741 : : // changed to return void. A zero-sized object can have a
1742 : : // (zero-sized) field, so support that case.
1743 : 2430834 : if (TREE_TYPE(struct_tree) == void_type_node)
1744 : : return bstruct;
1745 : :
1746 : 2430834 : gcc_assert(TREE_CODE(TREE_TYPE(struct_tree)) == RECORD_TYPE);
1747 : 2430834 : tree field = TYPE_FIELDS(TREE_TYPE(struct_tree));
1748 : 2430834 : if (field == NULL_TREE)
1749 : : {
1750 : : // This can happen for a type which refers to itself indirectly
1751 : : // and then turns out to be erroneous.
1752 : 0 : return this->error_expression();
1753 : : }
1754 : 6036719 : for (unsigned int i = index; i > 0; --i)
1755 : : {
1756 : 3605885 : field = DECL_CHAIN(field);
1757 : 3605885 : gcc_assert(field != NULL_TREE);
1758 : : }
1759 : 2430834 : if (TREE_TYPE(field) == error_mark_node)
1760 : 0 : return this->error_expression();
1761 : 2430834 : tree ret = fold_build3_loc(location.gcc_location(), COMPONENT_REF,
1762 : 2430834 : TREE_TYPE(field), struct_tree, field,
1763 : : NULL_TREE);
1764 : 2430834 : if (TREE_CONSTANT(struct_tree))
1765 : 135 : TREE_CONSTANT(ret) = 1;
1766 : 2430834 : return this->make_expression(ret);
1767 : : }
1768 : :
1769 : : // Return an expression that executes BSTAT before BEXPR.
1770 : :
1771 : : Bexpression*
1772 : 450088 : Gcc_backend::compound_expression(Bstatement* bstat, Bexpression* bexpr,
1773 : : Location location)
1774 : : {
1775 : 450088 : tree stat = bstat->get_tree();
1776 : 450088 : tree expr = bexpr->get_tree();
1777 : 450088 : if (stat == error_mark_node || expr == error_mark_node)
1778 : 9 : return this->error_expression();
1779 : 450079 : tree ret = fold_build2_loc(location.gcc_location(), COMPOUND_EXPR,
1780 : 450079 : TREE_TYPE(expr), stat, expr);
1781 : 450079 : return this->make_expression(ret);
1782 : : }
1783 : :
1784 : : // Return an expression that executes THEN_EXPR if CONDITION is true, or
1785 : : // ELSE_EXPR otherwise.
1786 : :
1787 : : Bexpression*
1788 : 558018 : Gcc_backend::conditional_expression(Bfunction*, Btype* btype,
1789 : : Bexpression* condition,
1790 : : Bexpression* then_expr,
1791 : : Bexpression* else_expr, Location location)
1792 : : {
1793 : 558018 : tree type_tree = btype == NULL ? void_type_node : btype->get_tree();
1794 : 558018 : tree cond_tree = condition->get_tree();
1795 : 558018 : tree then_tree = then_expr->get_tree();
1796 : 558018 : tree else_tree = else_expr == NULL ? NULL_TREE : else_expr->get_tree();
1797 : 558018 : if (type_tree == error_mark_node
1798 : 558018 : || cond_tree == error_mark_node
1799 : 558018 : || then_tree == error_mark_node
1800 : 558018 : || else_tree == error_mark_node)
1801 : 0 : return this->error_expression();
1802 : 558018 : tree ret = build3_loc(location.gcc_location(), COND_EXPR, type_tree,
1803 : : cond_tree, then_tree, else_tree);
1804 : 558018 : return this->make_expression(ret);
1805 : : }
1806 : :
1807 : : // Return an expression for the unary operation OP EXPR.
1808 : :
1809 : : Bexpression*
1810 : 108286 : Gcc_backend::unary_expression(Operator op, Bexpression* expr, Location location)
1811 : : {
1812 : 108286 : tree expr_tree = expr->get_tree();
1813 : 108286 : if (expr_tree == error_mark_node
1814 : 108286 : || TREE_TYPE(expr_tree) == error_mark_node)
1815 : 1 : return this->error_expression();
1816 : :
1817 : 108285 : tree type_tree = TREE_TYPE(expr_tree);
1818 : 108285 : enum tree_code code;
1819 : 108285 : switch (op)
1820 : : {
1821 : 10894 : case OPERATOR_MINUS:
1822 : 10894 : {
1823 : 10894 : tree computed_type = excess_precision_type(type_tree);
1824 : 10894 : if (computed_type != NULL_TREE)
1825 : : {
1826 : 464 : expr_tree = convert(computed_type, expr_tree);
1827 : 464 : type_tree = computed_type;
1828 : : }
1829 : : code = NEGATE_EXPR;
1830 : : break;
1831 : : }
1832 : : case OPERATOR_NOT:
1833 : : code = TRUTH_NOT_EXPR;
1834 : : break;
1835 : 3062 : case OPERATOR_XOR:
1836 : 3062 : code = BIT_NOT_EXPR;
1837 : 3062 : break;
1838 : 0 : default:
1839 : 0 : gcc_unreachable();
1840 : 108285 : break;
1841 : : }
1842 : :
1843 : 108285 : tree ret = fold_build1_loc(location.gcc_location(), code, type_tree,
1844 : : expr_tree);
1845 : 108285 : return this->make_expression(ret);
1846 : : }
1847 : :
1848 : : // Convert a gofrontend operator to an equivalent tree_code.
1849 : :
1850 : : static enum tree_code
1851 : 2287974 : operator_to_tree_code(Operator op, tree type)
1852 : : {
1853 : 2287974 : enum tree_code code;
1854 : 2287974 : switch (op)
1855 : : {
1856 : : case OPERATOR_EQEQ:
1857 : : code = EQ_EXPR;
1858 : : break;
1859 : 162332 : case OPERATOR_NOTEQ:
1860 : 162332 : code = NE_EXPR;
1861 : 162332 : break;
1862 : 222537 : case OPERATOR_LT:
1863 : 222537 : code = LT_EXPR;
1864 : 222537 : break;
1865 : 92034 : case OPERATOR_LE:
1866 : 92034 : code = LE_EXPR;
1867 : 92034 : break;
1868 : 37325 : case OPERATOR_GT:
1869 : 37325 : code = GT_EXPR;
1870 : 37325 : break;
1871 : 225125 : case OPERATOR_GE:
1872 : 225125 : code = GE_EXPR;
1873 : 225125 : break;
1874 : 16 : case OPERATOR_OROR:
1875 : 16 : code = TRUTH_ORIF_EXPR;
1876 : 16 : break;
1877 : 217786 : case OPERATOR_ANDAND:
1878 : 217786 : code = TRUTH_ANDIF_EXPR;
1879 : 217786 : break;
1880 : 142275 : case OPERATOR_PLUS:
1881 : 142275 : code = PLUS_EXPR;
1882 : 142275 : break;
1883 : 150242 : case OPERATOR_MINUS:
1884 : 150242 : code = MINUS_EXPR;
1885 : 150242 : break;
1886 : 127493 : case OPERATOR_OR:
1887 : 127493 : code = BIT_IOR_EXPR;
1888 : 127493 : break;
1889 : 3908 : case OPERATOR_XOR:
1890 : 3908 : code = BIT_XOR_EXPR;
1891 : 3908 : break;
1892 : 28250 : case OPERATOR_MULT:
1893 : 28250 : code = MULT_EXPR;
1894 : 28250 : break;
1895 : 8928 : case OPERATOR_DIV:
1896 : 8928 : if (TREE_CODE(type) == REAL_TYPE || TREE_CODE(type) == COMPLEX_TYPE)
1897 : : code = RDIV_EXPR;
1898 : : else
1899 : 2287974 : code = TRUNC_DIV_EXPR;
1900 : : break;
1901 : 4242 : case OPERATOR_MOD:
1902 : 4242 : code = TRUNC_MOD_EXPR;
1903 : 4242 : break;
1904 : 129742 : case OPERATOR_LSHIFT:
1905 : 129742 : code = LSHIFT_EXPR;
1906 : 129742 : break;
1907 : 13650 : case OPERATOR_RSHIFT:
1908 : 13650 : code = RSHIFT_EXPR;
1909 : 13650 : break;
1910 : : case OPERATOR_AND:
1911 : 17617 : code = BIT_AND_EXPR;
1912 : : break;
1913 : : case OPERATOR_BITCLEAR:
1914 : 17617 : code = BIT_AND_EXPR;
1915 : : break;
1916 : 0 : default:
1917 : 0 : gcc_unreachable();
1918 : : }
1919 : :
1920 : 2287974 : return code;
1921 : : }
1922 : :
1923 : : // Return an expression for the binary operation LEFT OP RIGHT.
1924 : :
1925 : : Bexpression*
1926 : 2287975 : Gcc_backend::binary_expression(Operator op, Bexpression* left,
1927 : : Bexpression* right, Location location)
1928 : : {
1929 : 2287975 : tree left_tree = left->get_tree();
1930 : 2287975 : tree right_tree = right->get_tree();
1931 : 2287975 : if (left_tree == error_mark_node
1932 : 2287975 : || right_tree == error_mark_node)
1933 : 1 : return this->error_expression();
1934 : 2287974 : enum tree_code code = operator_to_tree_code(op, TREE_TYPE(left_tree));
1935 : :
1936 : 2287974 : bool use_left_type = op != OPERATOR_OROR && op != OPERATOR_ANDAND;
1937 : 2287974 : tree type_tree = use_left_type ? TREE_TYPE(left_tree) : TREE_TYPE(right_tree);
1938 : 2287974 : tree computed_type = excess_precision_type(type_tree);
1939 : 2287974 : if (computed_type != NULL_TREE)
1940 : : {
1941 : 8586 : left_tree = convert(computed_type, left_tree);
1942 : 8586 : right_tree = convert(computed_type, right_tree);
1943 : 8586 : type_tree = computed_type;
1944 : : }
1945 : :
1946 : : // For comparison operators, the resulting type should be boolean.
1947 : 2287974 : switch (op)
1948 : : {
1949 : 1443825 : case OPERATOR_EQEQ:
1950 : 1443825 : case OPERATOR_NOTEQ:
1951 : 1443825 : case OPERATOR_LT:
1952 : 1443825 : case OPERATOR_LE:
1953 : 1443825 : case OPERATOR_GT:
1954 : 1443825 : case OPERATOR_GE:
1955 : 1443825 : type_tree = boolean_type_node;
1956 : 1443825 : break;
1957 : : default:
1958 : : break;
1959 : : }
1960 : :
1961 : 2287974 : tree ret = fold_build2_loc(location.gcc_location(), code, type_tree,
1962 : : left_tree, right_tree);
1963 : 2287974 : return this->make_expression(ret);
1964 : : }
1965 : :
1966 : : // Return an expression that constructs BTYPE with VALS.
1967 : :
1968 : : Bexpression*
1969 : 2873975 : Gcc_backend::constructor_expression(Btype* btype,
1970 : : const std::vector<Bexpression*>& vals,
1971 : : Location location)
1972 : : {
1973 : 2873975 : tree type_tree = btype->get_tree();
1974 : 2873975 : if (type_tree == error_mark_node)
1975 : 0 : return this->error_expression();
1976 : :
1977 : 2873975 : vec<constructor_elt, va_gc> *init;
1978 : 2873975 : vec_alloc(init, vals.size());
1979 : :
1980 : 2873975 : tree sink = NULL_TREE;
1981 : 2873975 : bool is_constant = true;
1982 : 2873975 : tree field = TYPE_FIELDS(type_tree);
1983 : 2873975 : for (std::vector<Bexpression*>::const_iterator p = vals.begin();
1984 : 12734453 : p != vals.end();
1985 : 9860478 : ++p, field = DECL_CHAIN(field))
1986 : : {
1987 : 9860494 : gcc_assert(field != NULL_TREE);
1988 : 9860494 : tree val = (*p)->get_tree();
1989 : 9860494 : if (TREE_TYPE(field) == error_mark_node
1990 : 9860494 : || val == error_mark_node
1991 : 19720972 : || TREE_TYPE(val) == error_mark_node)
1992 : 16 : return this->error_expression();
1993 : :
1994 : 9860478 : if (int_size_in_bytes(TREE_TYPE(field)) == 0)
1995 : : {
1996 : : // GIMPLE cannot represent indices of zero-sized types so
1997 : : // trying to construct a map with zero-sized keys might lead
1998 : : // to errors. Instead, we evaluate each expression that
1999 : : // would have been added as a map element for its
2000 : : // side-effects and construct an empty map.
2001 : 810 : append_to_statement_list(val, &sink);
2002 : 810 : continue;
2003 : : }
2004 : :
2005 : 9859668 : constructor_elt empty = {NULL, NULL};
2006 : 9859668 : constructor_elt* elt = init->quick_push(empty);
2007 : 9859668 : elt->index = field;
2008 : 9859668 : elt->value = this->convert_tree(TREE_TYPE(field), val, location);
2009 : 9859668 : if (!TREE_CONSTANT(elt->value))
2010 : 597767 : is_constant = false;
2011 : : }
2012 : 2873959 : gcc_assert(field == NULL_TREE);
2013 : 2873959 : tree ret = build_constructor(type_tree, init);
2014 : 2873959 : if (is_constant)
2015 : 2462637 : TREE_CONSTANT(ret) = 1;
2016 : 2873959 : if (sink != NULL_TREE)
2017 : 0 : ret = fold_build2_loc(location.gcc_location(), COMPOUND_EXPR,
2018 : : type_tree, sink, ret);
2019 : 2873959 : return this->make_expression(ret);
2020 : : }
2021 : :
2022 : : Bexpression*
2023 : 440904 : Gcc_backend::array_constructor_expression(
2024 : : Btype* array_btype, const std::vector<unsigned long>& indexes,
2025 : : const std::vector<Bexpression*>& vals, Location location)
2026 : : {
2027 : 440904 : tree type_tree = array_btype->get_tree();
2028 : 440904 : if (type_tree == error_mark_node)
2029 : 1 : return this->error_expression();
2030 : :
2031 : 440903 : gcc_assert(indexes.size() == vals.size());
2032 : :
2033 : 440903 : tree element_type = TREE_TYPE(type_tree);
2034 : 440903 : HOST_WIDE_INT element_size = int_size_in_bytes(element_type);
2035 : 440903 : vec<constructor_elt, va_gc> *init;
2036 : 440903 : vec_alloc(init, element_size == 0 ? 0 : vals.size());
2037 : :
2038 : 440903 : tree sink = NULL_TREE;
2039 : 440903 : bool is_constant = true;
2040 : 2372672 : for (size_t i = 0; i < vals.size(); ++i)
2041 : : {
2042 : 1931774 : tree index = size_int(indexes[i]);
2043 : 1931774 : tree val = (vals[i])->get_tree();
2044 : :
2045 : 1931774 : if (index == error_mark_node
2046 : 1931774 : || val == error_mark_node)
2047 : 5 : return this->error_expression();
2048 : :
2049 : 1931769 : if (element_size == 0)
2050 : : {
2051 : : // GIMPLE cannot represent arrays of zero-sized types so trying
2052 : : // to construct an array of zero-sized values might lead to errors.
2053 : : // Instead, we evaluate each expression that would have been added as
2054 : : // an array value for its side-effects and construct an empty array.
2055 : 9 : append_to_statement_list(val, &sink);
2056 : 9 : continue;
2057 : : }
2058 : :
2059 : 1931760 : if (!TREE_CONSTANT(val))
2060 : 156463 : is_constant = false;
2061 : :
2062 : 1931760 : constructor_elt empty = {NULL, NULL};
2063 : 1931760 : constructor_elt* elt = init->quick_push(empty);
2064 : 1931760 : elt->index = index;
2065 : 1931760 : elt->value = val;
2066 : : }
2067 : :
2068 : 440898 : tree ret = build_constructor(type_tree, init);
2069 : 440898 : if (is_constant)
2070 : 364876 : TREE_CONSTANT(ret) = 1;
2071 : 440898 : if (sink != NULL_TREE)
2072 : 0 : ret = fold_build2_loc(location.gcc_location(), COMPOUND_EXPR,
2073 : : type_tree, sink, ret);
2074 : 440898 : return this->make_expression(ret);
2075 : : }
2076 : :
2077 : : // Return an expression for the address of BASE[INDEX].
2078 : :
2079 : : Bexpression*
2080 : 160626 : Gcc_backend::pointer_offset_expression(Bexpression* base, Bexpression* index,
2081 : : Location location)
2082 : : {
2083 : 160626 : tree base_tree = base->get_tree();
2084 : 160626 : tree index_tree = index->get_tree();
2085 : 160626 : tree element_type_tree = TREE_TYPE(TREE_TYPE(base_tree));
2086 : 160626 : if (base_tree == error_mark_node
2087 : 160626 : || TREE_TYPE(base_tree) == error_mark_node
2088 : 160626 : || index_tree == error_mark_node
2089 : 321252 : || element_type_tree == error_mark_node)
2090 : 0 : return this->error_expression();
2091 : :
2092 : 160626 : tree element_size = TYPE_SIZE_UNIT(element_type_tree);
2093 : 160626 : index_tree = fold_convert_loc(location.gcc_location(), sizetype, index_tree);
2094 : 160626 : tree offset = fold_build2_loc(location.gcc_location(), MULT_EXPR, sizetype,
2095 : : index_tree, element_size);
2096 : 160626 : tree ptr = fold_build2_loc(location.gcc_location(), POINTER_PLUS_EXPR,
2097 : 160626 : TREE_TYPE(base_tree), base_tree, offset);
2098 : 160626 : return this->make_expression(ptr);
2099 : : }
2100 : :
2101 : : // Return an expression representing ARRAY[INDEX]
2102 : :
2103 : : Bexpression*
2104 : 66928 : Gcc_backend::array_index_expression(Bexpression* array, Bexpression* index,
2105 : : Location location)
2106 : : {
2107 : 66928 : tree array_tree = array->get_tree();
2108 : 66928 : tree index_tree = index->get_tree();
2109 : 66928 : if (array_tree == error_mark_node
2110 : 66928 : || TREE_TYPE(array_tree) == error_mark_node
2111 : 133856 : || index_tree == error_mark_node)
2112 : 0 : return this->error_expression();
2113 : :
2114 : : // A function call that returns a zero sized object will have been
2115 : : // changed to return void. If we see void here, assume we are
2116 : : // dealing with a zero sized type and just evaluate the operands.
2117 : 66928 : tree ret;
2118 : 66928 : if (TREE_TYPE(array_tree) != void_type_node)
2119 : 66927 : ret = build4_loc(location.gcc_location(), ARRAY_REF,
2120 : 66927 : TREE_TYPE(TREE_TYPE(array_tree)), array_tree,
2121 : : index_tree, NULL_TREE, NULL_TREE);
2122 : : else
2123 : 1 : ret = fold_build2_loc(location.gcc_location(), COMPOUND_EXPR,
2124 : : void_type_node, array_tree, index_tree);
2125 : :
2126 : 66928 : return this->make_expression(ret);
2127 : : }
2128 : :
2129 : : // Create an expression for a call to FN_EXPR with FN_ARGS.
2130 : : Bexpression*
2131 : 1791467 : Gcc_backend::call_expression(Bfunction*, // containing fcn for call
2132 : : Bexpression* fn_expr,
2133 : : const std::vector<Bexpression*>& fn_args,
2134 : : Bexpression* chain_expr,
2135 : : Location location)
2136 : : {
2137 : 1791467 : tree fn = fn_expr->get_tree();
2138 : 1791467 : if (fn == error_mark_node || TREE_TYPE(fn) == error_mark_node)
2139 : 4 : return this->error_expression();
2140 : :
2141 : 1791463 : gcc_assert(FUNCTION_POINTER_TYPE_P(TREE_TYPE(fn)));
2142 : 1791463 : tree rettype = TREE_TYPE(TREE_TYPE(TREE_TYPE(fn)));
2143 : :
2144 : 1791463 : size_t nargs = fn_args.size();
2145 : 3350487 : tree* args = nargs == 0 ? NULL : new tree[nargs];
2146 : 5002034 : for (size_t i = 0; i < nargs; ++i)
2147 : : {
2148 : 3210581 : args[i] = fn_args.at(i)->get_tree();
2149 : 3210581 : if (args[i] == error_mark_node)
2150 : 10 : return this->error_expression();
2151 : 3210571 : if (TREE_TYPE(args[i]) == void_type_node)
2152 : : {
2153 : : // This can happen for a case like f(g()) where g returns a
2154 : : // zero-sized type, because in that case we've changed g to
2155 : : // return void.
2156 : 0 : tree t = TYPE_ARG_TYPES(TREE_TYPE(TREE_TYPE(fn)));
2157 : 0 : for (size_t j = 0; j < i; ++j)
2158 : 0 : t = TREE_CHAIN(t);
2159 : 0 : tree arg_type = TREE_TYPE(TREE_VALUE(t));
2160 : 0 : args[i] = fold_build2_loc(EXPR_LOCATION(args[i]), COMPOUND_EXPR,
2161 : : arg_type, args[i],
2162 : : build_zero_cst(arg_type));
2163 : : }
2164 : : }
2165 : :
2166 : 1791453 : tree fndecl = fn;
2167 : 1791453 : if (TREE_CODE(fndecl) == ADDR_EXPR)
2168 : 1737185 : fndecl = TREE_OPERAND(fndecl, 0);
2169 : :
2170 : : // This is to support builtin math functions when using 80387 math.
2171 : 1791453 : tree excess_type = NULL_TREE;
2172 : 1791453 : if (optimize
2173 : 1632132 : && TREE_CODE(fndecl) == FUNCTION_DECL
2174 : 1577882 : && fndecl_built_in_p (fndecl, BUILT_IN_NORMAL)
2175 : 59563 : && DECL_IS_UNDECLARED_BUILTIN (fndecl)
2176 : 59563 : && nargs > 0
2177 : 1850024 : && ((SCALAR_FLOAT_TYPE_P(rettype)
2178 : 341 : && SCALAR_FLOAT_TYPE_P(TREE_TYPE(args[0])))
2179 : 58230 : || (COMPLEX_FLOAT_TYPE_P(rettype)
2180 : 0 : && COMPLEX_FLOAT_TYPE_P(TREE_TYPE(args[0])))))
2181 : : {
2182 : 341 : excess_type = excess_precision_type(TREE_TYPE(args[0]));
2183 : 341 : if (excess_type != NULL_TREE)
2184 : : {
2185 : 164 : tree excess_fndecl = mathfn_built_in(excess_type,
2186 : : DECL_FUNCTION_CODE(fndecl));
2187 : 164 : if (excess_fndecl == NULL_TREE)
2188 : : excess_type = NULL_TREE;
2189 : : else
2190 : : {
2191 : 164 : fn = build_fold_addr_expr_loc(location.gcc_location(),
2192 : : excess_fndecl);
2193 : 351 : for (size_t i = 0; i < nargs; ++i)
2194 : : {
2195 : 187 : if (SCALAR_FLOAT_TYPE_P(TREE_TYPE(args[i]))
2196 : 187 : || COMPLEX_FLOAT_TYPE_P(TREE_TYPE(args[i])))
2197 : 176 : args[i] = ::convert(excess_type, args[i]);
2198 : : }
2199 : : }
2200 : : }
2201 : : }
2202 : :
2203 : 1791453 : tree ret =
2204 : 1791453 : build_call_array_loc(location.gcc_location(),
2205 : : excess_type != NULL_TREE ? excess_type : rettype,
2206 : : fn, nargs, args);
2207 : :
2208 : 1791453 : if (chain_expr)
2209 : 23187 : CALL_EXPR_STATIC_CHAIN (ret) = chain_expr->get_tree();
2210 : :
2211 : 1791453 : if (excess_type != NULL_TREE)
2212 : : {
2213 : : // Calling convert here can undo our excess precision change.
2214 : : // That may or may not be a bug in convert_to_real.
2215 : 164 : ret = build1_loc(location.gcc_location(), NOP_EXPR, rettype, ret);
2216 : : }
2217 : :
2218 : 1791453 : delete[] args;
2219 : 1791453 : return this->make_expression(ret);
2220 : : }
2221 : :
2222 : : // An expression as a statement.
2223 : :
2224 : : Bstatement*
2225 : 1009936 : Gcc_backend::expression_statement(Bfunction*, Bexpression* expr)
2226 : : {
2227 : 1009936 : return this->make_statement(expr->get_tree());
2228 : : }
2229 : :
2230 : : // Variable initialization.
2231 : :
2232 : : Bstatement*
2233 : 645172 : Gcc_backend::init_statement(Bfunction*, Bvariable* var, Bexpression* init)
2234 : : {
2235 : 645172 : tree var_tree = var->get_decl();
2236 : 645172 : tree init_tree = init->get_tree();
2237 : 645172 : if (var_tree == error_mark_node || init_tree == error_mark_node)
2238 : 6 : return this->error_statement();
2239 : 645166 : gcc_assert(TREE_CODE(var_tree) == VAR_DECL);
2240 : :
2241 : : // To avoid problems with GNU ld, we don't make zero-sized
2242 : : // externally visible variables. That might lead us to doing an
2243 : : // initialization of a zero-sized expression to a non-zero sized
2244 : : // variable, or vice-versa. Avoid crashes by omitting the
2245 : : // initializer. Such initializations don't mean anything anyhow.
2246 : 645166 : if (int_size_in_bytes(TREE_TYPE(var_tree)) != 0
2247 : 643854 : && init_tree != NULL_TREE
2248 : 643854 : && TREE_TYPE(init_tree) != void_type_node
2249 : 1289020 : && int_size_in_bytes(TREE_TYPE(init_tree)) != 0)
2250 : : {
2251 : 643854 : DECL_INITIAL(var_tree) = init_tree;
2252 : 643854 : init_tree = NULL_TREE;
2253 : : }
2254 : :
2255 : 645166 : tree ret = build1_loc(DECL_SOURCE_LOCATION(var_tree), DECL_EXPR,
2256 : : void_type_node, var_tree);
2257 : 645166 : if (init_tree != NULL_TREE)
2258 : 1312 : ret = build2_loc(DECL_SOURCE_LOCATION(var_tree), COMPOUND_EXPR,
2259 : : void_type_node, init_tree, ret);
2260 : :
2261 : 645166 : return this->make_statement(ret);
2262 : : }
2263 : :
2264 : : // Assignment.
2265 : :
2266 : : Bstatement*
2267 : 1406077 : Gcc_backend::assignment_statement(Bfunction* bfn, Bexpression* lhs,
2268 : : Bexpression* rhs, Location location)
2269 : : {
2270 : 1406077 : tree lhs_tree = lhs->get_tree();
2271 : 1406077 : tree rhs_tree = rhs->get_tree();
2272 : 1406077 : if (lhs_tree == error_mark_node || rhs_tree == error_mark_node)
2273 : 121 : return this->error_statement();
2274 : :
2275 : : // To avoid problems with GNU ld, we don't make zero-sized
2276 : : // externally visible variables. That might lead us to doing an
2277 : : // assignment of a zero-sized expression to a non-zero sized
2278 : : // expression; avoid crashes here by avoiding assignments of
2279 : : // zero-sized expressions. Such assignments don't really mean
2280 : : // anything anyhow.
2281 : 1405956 : if (TREE_TYPE(lhs_tree) == void_type_node
2282 : 1405956 : || int_size_in_bytes(TREE_TYPE(lhs_tree)) == 0
2283 : 1400538 : || TREE_TYPE(rhs_tree) == void_type_node
2284 : 2806494 : || int_size_in_bytes(TREE_TYPE(rhs_tree)) == 0)
2285 : 5418 : return this->compound_statement(this->expression_statement(bfn, lhs),
2286 : 10836 : this->expression_statement(bfn, rhs));
2287 : :
2288 : 1400538 : rhs_tree = this->convert_tree(TREE_TYPE(lhs_tree), rhs_tree, location);
2289 : :
2290 : 1400538 : return this->make_statement(fold_build2_loc(location.gcc_location(),
2291 : : MODIFY_EXPR,
2292 : : void_type_node,
2293 : 1400538 : lhs_tree, rhs_tree));
2294 : : }
2295 : :
2296 : : // Return.
2297 : :
2298 : : Bstatement*
2299 : 377001 : Gcc_backend::return_statement(Bfunction* bfunction,
2300 : : const std::vector<Bexpression*>& vals,
2301 : : Location location)
2302 : : {
2303 : 377001 : tree fntree = bfunction->get_tree();
2304 : 377001 : if (fntree == error_mark_node)
2305 : 0 : return this->error_statement();
2306 : 377001 : tree result = DECL_RESULT(fntree);
2307 : 377001 : if (result == error_mark_node)
2308 : 0 : return this->error_statement();
2309 : :
2310 : : // If the result size is zero bytes, we have set the function type
2311 : : // to have a result type of void, so don't return anything.
2312 : : // See the function_type method.
2313 : 377001 : tree res_type = TREE_TYPE(result);
2314 : 377001 : if (res_type == void_type_node || int_size_in_bytes(res_type) == 0)
2315 : : {
2316 : 10956 : tree stmt_list = NULL_TREE;
2317 : 10970 : for (std::vector<Bexpression*>::const_iterator p = vals.begin();
2318 : 10970 : p != vals.end();
2319 : 14 : p++)
2320 : : {
2321 : 14 : tree val = (*p)->get_tree();
2322 : 14 : if (val == error_mark_node)
2323 : 0 : return this->error_statement();
2324 : 14 : append_to_statement_list(val, &stmt_list);
2325 : : }
2326 : 10956 : tree ret = fold_build1_loc(location.gcc_location(), RETURN_EXPR,
2327 : : void_type_node, NULL_TREE);
2328 : 10956 : append_to_statement_list(ret, &stmt_list);
2329 : 10956 : return this->make_statement(stmt_list);
2330 : : }
2331 : :
2332 : 366045 : tree ret;
2333 : 366045 : if (vals.empty())
2334 : 0 : ret = fold_build1_loc(location.gcc_location(), RETURN_EXPR, void_type_node,
2335 : : NULL_TREE);
2336 : 366045 : else if (vals.size() == 1)
2337 : : {
2338 : 304270 : tree val = vals.front()->get_tree();
2339 : 304270 : if (val == error_mark_node)
2340 : 0 : return this->error_statement();
2341 : 304270 : tree set = fold_build2_loc(location.gcc_location(), MODIFY_EXPR,
2342 : : void_type_node, result,
2343 : 304270 : vals.front()->get_tree());
2344 : 304270 : ret = fold_build1_loc(location.gcc_location(), RETURN_EXPR,
2345 : : void_type_node, set);
2346 : : }
2347 : : else
2348 : : {
2349 : : // To return multiple values, copy the values into a temporary
2350 : : // variable of the right structure type, and then assign the
2351 : : // temporary variable to the DECL_RESULT in the return
2352 : : // statement.
2353 : 61775 : tree stmt_list = NULL_TREE;
2354 : 61775 : tree rettype = TREE_TYPE(result);
2355 : :
2356 : 61775 : if (DECL_STRUCT_FUNCTION(fntree) == NULL)
2357 : 283 : push_struct_function(fntree);
2358 : : else
2359 : 61492 : push_cfun(DECL_STRUCT_FUNCTION(fntree));
2360 : 61775 : tree rettmp = create_tmp_var(rettype, "RESULT");
2361 : 61775 : pop_cfun();
2362 : :
2363 : 61775 : tree field = TYPE_FIELDS(rettype);
2364 : 61775 : for (std::vector<Bexpression*>::const_iterator p = vals.begin();
2365 : 198361 : p != vals.end();
2366 : 136586 : p++, field = DECL_CHAIN(field))
2367 : : {
2368 : 136586 : gcc_assert(field != NULL_TREE);
2369 : 136586 : tree ref = fold_build3_loc(location.gcc_location(), COMPONENT_REF,
2370 : 136586 : TREE_TYPE(field), rettmp, field,
2371 : : NULL_TREE);
2372 : 136586 : tree val = (*p)->get_tree();
2373 : 136586 : if (val == error_mark_node)
2374 : 0 : return this->error_statement();
2375 : 273172 : tree set = fold_build2_loc(location.gcc_location(), MODIFY_EXPR,
2376 : : void_type_node,
2377 : 136586 : ref, (*p)->get_tree());
2378 : 136586 : append_to_statement_list(set, &stmt_list);
2379 : : }
2380 : 61775 : gcc_assert(field == NULL_TREE);
2381 : 61775 : tree set = fold_build2_loc(location.gcc_location(), MODIFY_EXPR,
2382 : : void_type_node,
2383 : : result, rettmp);
2384 : 61775 : tree ret_expr = fold_build1_loc(location.gcc_location(), RETURN_EXPR,
2385 : : void_type_node, set);
2386 : 61775 : append_to_statement_list(ret_expr, &stmt_list);
2387 : 61775 : ret = stmt_list;
2388 : : }
2389 : 366045 : return this->make_statement(ret);
2390 : : }
2391 : :
2392 : : // Create a statement that attempts to execute BSTAT and calls EXCEPT_STMT if an
2393 : : // error occurs. EXCEPT_STMT may be NULL. FINALLY_STMT may be NULL and if not
2394 : : // NULL, it will always be executed. This is used for handling defers in Go
2395 : : // functions. In C++, the resulting code is of this form:
2396 : : // try { BSTAT; } catch { EXCEPT_STMT; } finally { FINALLY_STMT; }
2397 : :
2398 : : Bstatement*
2399 : 8353 : Gcc_backend::exception_handler_statement(Bstatement* bstat,
2400 : : Bstatement* except_stmt,
2401 : : Bstatement* finally_stmt,
2402 : : Location location)
2403 : : {
2404 : 8353 : tree stat_tree = bstat->get_tree();
2405 : 8353 : tree except_tree = except_stmt == NULL ? NULL_TREE : except_stmt->get_tree();
2406 : 8353 : tree finally_tree = finally_stmt == NULL
2407 : 8353 : ? NULL_TREE
2408 : 8353 : : finally_stmt->get_tree();
2409 : :
2410 : 8353 : if (stat_tree == error_mark_node
2411 : 8353 : || except_tree == error_mark_node
2412 : 8353 : || finally_tree == error_mark_node)
2413 : 0 : return this->error_statement();
2414 : :
2415 : 8353 : if (except_tree != NULL_TREE)
2416 : 8353 : stat_tree = build2_loc(location.gcc_location(), TRY_CATCH_EXPR,
2417 : : void_type_node, stat_tree,
2418 : : build2_loc(location.gcc_location(), CATCH_EXPR,
2419 : : void_type_node, NULL, except_tree));
2420 : 8353 : if (finally_tree != NULL_TREE)
2421 : 8353 : stat_tree = build2_loc(location.gcc_location(), TRY_FINALLY_EXPR,
2422 : : void_type_node, stat_tree, finally_tree);
2423 : 8353 : return this->make_statement(stat_tree);
2424 : : }
2425 : :
2426 : : // If.
2427 : :
2428 : : Bstatement*
2429 : 698866 : Gcc_backend::if_statement(Bfunction*, Bexpression* condition,
2430 : : Bblock* then_block, Bblock* else_block,
2431 : : Location location)
2432 : : {
2433 : 698866 : tree cond_tree = condition->get_tree();
2434 : 698866 : tree then_tree = then_block->get_tree();
2435 : 698866 : tree else_tree = else_block == NULL ? NULL_TREE : else_block->get_tree();
2436 : 698866 : if (cond_tree == error_mark_node
2437 : 698862 : || then_tree == error_mark_node
2438 : 698862 : || else_tree == error_mark_node)
2439 : 4 : return this->error_statement();
2440 : 698862 : tree ret = build3_loc(location.gcc_location(), COND_EXPR, void_type_node,
2441 : : cond_tree, then_tree, else_tree);
2442 : 698862 : return this->make_statement(ret);
2443 : : }
2444 : :
2445 : : // Switch.
2446 : :
2447 : : Bstatement*
2448 : 7785 : Gcc_backend::switch_statement(
2449 : : Bfunction* function,
2450 : : Bexpression* value,
2451 : : const std::vector<std::vector<Bexpression*> >& cases,
2452 : : const std::vector<Bstatement*>& statements,
2453 : : Location switch_location)
2454 : : {
2455 : 7785 : gcc_assert(cases.size() == statements.size());
2456 : :
2457 : 7785 : tree decl = function->get_tree();
2458 : 7785 : if (DECL_STRUCT_FUNCTION(decl) == NULL)
2459 : 2 : push_struct_function(decl);
2460 : : else
2461 : 7783 : push_cfun(DECL_STRUCT_FUNCTION(decl));
2462 : :
2463 : 7785 : tree stmt_list = NULL_TREE;
2464 : 7785 : std::vector<std::vector<Bexpression*> >::const_iterator pc = cases.begin();
2465 : 7785 : for (std::vector<Bstatement*>::const_iterator ps = statements.begin();
2466 : 39947 : ps != statements.end();
2467 : 32162 : ++ps, ++pc)
2468 : : {
2469 : 32165 : if (pc->empty())
2470 : : {
2471 : 4631 : location_t loc = (*ps != NULL
2472 : 4631 : ? EXPR_LOCATION((*ps)->get_tree())
2473 : 4631 : : UNKNOWN_LOCATION);
2474 : 4631 : tree label = create_artificial_label(loc);
2475 : 4631 : tree c = build_case_label(NULL_TREE, NULL_TREE, label);
2476 : 4631 : append_to_statement_list(c, &stmt_list);
2477 : : }
2478 : : else
2479 : : {
2480 : 39894 : for (std::vector<Bexpression*>::const_iterator pcv = pc->begin();
2481 : 67428 : pcv != pc->end();
2482 : 39894 : ++pcv)
2483 : : {
2484 : 39895 : tree t = (*pcv)->get_tree();
2485 : 39895 : if (t == error_mark_node)
2486 : 1 : return this->error_statement();
2487 : 39894 : location_t loc = EXPR_LOCATION(t);
2488 : 39894 : tree label = create_artificial_label(loc);
2489 : 39894 : tree c = build_case_label((*pcv)->get_tree(), NULL_TREE, label);
2490 : 39894 : append_to_statement_list(c, &stmt_list);
2491 : : }
2492 : : }
2493 : :
2494 : 32164 : if (*ps != NULL)
2495 : : {
2496 : 32147 : tree t = (*ps)->get_tree();
2497 : 32147 : if (t == error_mark_node)
2498 : 2 : return this->error_statement();
2499 : 32145 : append_to_statement_list(t, &stmt_list);
2500 : : }
2501 : : }
2502 : 7782 : pop_cfun();
2503 : :
2504 : 7782 : tree tv = value->get_tree();
2505 : 7782 : if (tv == error_mark_node)
2506 : 0 : return this->error_statement();
2507 : 7782 : tree t = build2_loc(switch_location.gcc_location(), SWITCH_EXPR,
2508 : : NULL_TREE, tv, stmt_list);
2509 : 7782 : return this->make_statement(t);
2510 : : }
2511 : :
2512 : : // Pair of statements.
2513 : :
2514 : : Bstatement*
2515 : 674300 : Gcc_backend::compound_statement(Bstatement* s1, Bstatement* s2)
2516 : : {
2517 : 674300 : tree stmt_list = NULL_TREE;
2518 : 674300 : tree t = s1->get_tree();
2519 : 674300 : if (t == error_mark_node)
2520 : 9 : return this->error_statement();
2521 : 674291 : append_to_statement_list(t, &stmt_list);
2522 : 674291 : t = s2->get_tree();
2523 : 674291 : if (t == error_mark_node)
2524 : 8 : return this->error_statement();
2525 : 674283 : append_to_statement_list(t, &stmt_list);
2526 : :
2527 : : // If neither statement has any side effects, stmt_list can be NULL
2528 : : // at this point.
2529 : 674283 : if (stmt_list == NULL_TREE)
2530 : 5415 : stmt_list = integer_zero_node;
2531 : :
2532 : 674283 : return this->make_statement(stmt_list);
2533 : : }
2534 : :
2535 : : // List of statements.
2536 : :
2537 : : Bstatement*
2538 : 337207 : Gcc_backend::statement_list(const std::vector<Bstatement*>& statements)
2539 : : {
2540 : 337207 : tree stmt_list = NULL_TREE;
2541 : 712684 : for (std::vector<Bstatement*>::const_iterator p = statements.begin();
2542 : 712684 : p != statements.end();
2543 : 375477 : ++p)
2544 : : {
2545 : 375522 : tree t = (*p)->get_tree();
2546 : 375522 : if (t == error_mark_node)
2547 : 45 : return this->error_statement();
2548 : 375477 : append_to_statement_list(t, &stmt_list);
2549 : : }
2550 : 337162 : return this->make_statement(stmt_list);
2551 : : }
2552 : :
2553 : : // Make a block. For some reason gcc uses a dual structure for
2554 : : // blocks: BLOCK tree nodes and BIND_EXPR tree nodes. Since the
2555 : : // BIND_EXPR node points to the BLOCK node, we store the BIND_EXPR in
2556 : : // the Bblock.
2557 : :
2558 : : Bblock*
2559 : 2859508 : Gcc_backend::block(Bfunction* function, Bblock* enclosing,
2560 : : const std::vector<Bvariable*>& vars,
2561 : : Location start_location,
2562 : : Location)
2563 : : {
2564 : 2859508 : tree block_tree = make_node(BLOCK);
2565 : 2859508 : if (enclosing == NULL)
2566 : : {
2567 : 551478 : tree fndecl = function->get_tree();
2568 : 551478 : gcc_assert(fndecl != NULL_TREE);
2569 : :
2570 : : // We may have already created a block for local variables when
2571 : : // we take the address of a parameter.
2572 : 551478 : if (DECL_INITIAL(fndecl) == NULL_TREE)
2573 : : {
2574 : 298765 : BLOCK_SUPERCONTEXT(block_tree) = fndecl;
2575 : 298765 : DECL_INITIAL(fndecl) = block_tree;
2576 : : }
2577 : : else
2578 : : {
2579 : 252713 : tree superblock_tree = DECL_INITIAL(fndecl);
2580 : 252713 : BLOCK_SUPERCONTEXT(block_tree) = superblock_tree;
2581 : 252713 : tree* pp;
2582 : 252713 : for (pp = &BLOCK_SUBBLOCKS(superblock_tree);
2583 : 1565373 : *pp != NULL_TREE;
2584 : 1312660 : pp = &BLOCK_CHAIN(*pp))
2585 : : ;
2586 : 252713 : *pp = block_tree;
2587 : : }
2588 : : }
2589 : : else
2590 : : {
2591 : 2308030 : tree superbind_tree = enclosing->get_tree();
2592 : 2308030 : tree superblock_tree = BIND_EXPR_BLOCK(superbind_tree);
2593 : 2308030 : gcc_assert(TREE_CODE(superblock_tree) == BLOCK);
2594 : :
2595 : 2308030 : BLOCK_SUPERCONTEXT(block_tree) = superblock_tree;
2596 : 2308030 : tree* pp;
2597 : 2308030 : for (pp = &BLOCK_SUBBLOCKS(superblock_tree);
2598 : 34292243 : *pp != NULL_TREE;
2599 : 31984213 : pp = &BLOCK_CHAIN(*pp))
2600 : : ;
2601 : 2308030 : *pp = block_tree;
2602 : : }
2603 : :
2604 : 2859508 : tree* pp = &BLOCK_VARS(block_tree);
2605 : 3504730 : for (std::vector<Bvariable*>::const_iterator pv = vars.begin();
2606 : 3504730 : pv != vars.end();
2607 : 645222 : ++pv)
2608 : : {
2609 : 645222 : *pp = (*pv)->get_decl();
2610 : 645222 : if (*pp != error_mark_node)
2611 : 645179 : pp = &DECL_CHAIN(*pp);
2612 : : }
2613 : 2859508 : *pp = NULL_TREE;
2614 : :
2615 : 2859508 : TREE_USED(block_tree) = 1;
2616 : :
2617 : 2859508 : tree bind_tree = build3_loc(start_location.gcc_location(), BIND_EXPR,
2618 : 2859508 : void_type_node, BLOCK_VARS(block_tree),
2619 : : NULL_TREE, block_tree);
2620 : 2859508 : TREE_SIDE_EFFECTS(bind_tree) = 1;
2621 : 2859508 : return new Bblock(bind_tree);
2622 : : }
2623 : :
2624 : : // Add statements to a block.
2625 : :
2626 : : void
2627 : 2856059 : Gcc_backend::block_add_statements(Bblock* bblock,
2628 : : const std::vector<Bstatement*>& statements)
2629 : : {
2630 : 2856059 : tree stmt_list = NULL_TREE;
2631 : 10106841 : for (std::vector<Bstatement*>::const_iterator p = statements.begin();
2632 : 10106841 : p != statements.end();
2633 : 7250782 : ++p)
2634 : : {
2635 : 7250782 : tree s = (*p)->get_tree();
2636 : 7250782 : if (s != error_mark_node)
2637 : 7246801 : append_to_statement_list(s, &stmt_list);
2638 : : }
2639 : :
2640 : 2856059 : tree bind_tree = bblock->get_tree();
2641 : 2856059 : gcc_assert(TREE_CODE(bind_tree) == BIND_EXPR);
2642 : 2856059 : BIND_EXPR_BODY(bind_tree) = stmt_list;
2643 : 2856059 : }
2644 : :
2645 : : // Return a block as a statement.
2646 : :
2647 : : Bstatement*
2648 : 1921601 : Gcc_backend::block_statement(Bblock* bblock)
2649 : : {
2650 : 1921601 : tree bind_tree = bblock->get_tree();
2651 : 1921601 : gcc_assert(TREE_CODE(bind_tree) == BIND_EXPR);
2652 : 1921601 : return this->make_statement(bind_tree);
2653 : : }
2654 : :
2655 : : // This is not static because we declare it with GTY(()) in go-c.h.
2656 : : tree go_non_zero_struct;
2657 : :
2658 : : // Return a type corresponding to TYPE with non-zero size.
2659 : :
2660 : : tree
2661 : 415 : Gcc_backend::non_zero_size_type(tree type)
2662 : : {
2663 : 415 : if (int_size_in_bytes(type) != 0)
2664 : : return type;
2665 : :
2666 : 413 : switch (TREE_CODE(type))
2667 : : {
2668 : 410 : case RECORD_TYPE:
2669 : 410 : if (TYPE_FIELDS(type) != NULL_TREE)
2670 : : {
2671 : 2 : tree ns = make_node(RECORD_TYPE);
2672 : 2 : tree field_trees = NULL_TREE;
2673 : 2 : tree *pp = &field_trees;
2674 : 2 : for (tree field = TYPE_FIELDS(type);
2675 : 4 : field != NULL_TREE;
2676 : 2 : field = DECL_CHAIN(field))
2677 : : {
2678 : 2 : tree ft = TREE_TYPE(field);
2679 : 2 : if (field == TYPE_FIELDS(type))
2680 : 2 : ft = non_zero_size_type(ft);
2681 : 2 : tree f = build_decl(DECL_SOURCE_LOCATION(field), FIELD_DECL,
2682 : 2 : DECL_NAME(field), ft);
2683 : 2 : DECL_CONTEXT(f) = ns;
2684 : 2 : *pp = f;
2685 : 2 : pp = &DECL_CHAIN(f);
2686 : : }
2687 : 2 : TYPE_FIELDS(ns) = field_trees;
2688 : 2 : layout_type(ns);
2689 : 2 : return ns;
2690 : : }
2691 : :
2692 : 408 : if (go_non_zero_struct == NULL_TREE)
2693 : : {
2694 : 298 : type = make_node(RECORD_TYPE);
2695 : 298 : tree field = build_decl(UNKNOWN_LOCATION, FIELD_DECL,
2696 : : get_identifier("dummy"),
2697 : : boolean_type_node);
2698 : 298 : DECL_CONTEXT(field) = type;
2699 : 298 : TYPE_FIELDS(type) = field;
2700 : 298 : layout_type(type);
2701 : 298 : go_non_zero_struct = type;
2702 : : }
2703 : 408 : return go_non_zero_struct;
2704 : :
2705 : 3 : case ARRAY_TYPE:
2706 : 3 : {
2707 : 3 : tree element_type = non_zero_size_type(TREE_TYPE(type));
2708 : 3 : return build_array_type_nelts(element_type, 1);
2709 : : }
2710 : :
2711 : 0 : default:
2712 : 0 : gcc_unreachable();
2713 : : }
2714 : :
2715 : : gcc_unreachable();
2716 : : }
2717 : :
2718 : : // Convert EXPR_TREE to TYPE_TREE. Sometimes the same unnamed Go type
2719 : : // can be created multiple times and thus have multiple tree
2720 : : // representations. Make sure this does not confuse the middle-end.
2721 : :
2722 : : tree
2723 : 13307779 : Gcc_backend::convert_tree(tree type_tree, tree expr_tree, Location location)
2724 : : {
2725 : 13307779 : if (type_tree == TREE_TYPE(expr_tree))
2726 : : return expr_tree;
2727 : :
2728 : 3355070 : if (type_tree == error_mark_node
2729 : 3355070 : || expr_tree == error_mark_node
2730 : 6710140 : || TREE_TYPE(expr_tree) == error_mark_node)
2731 : : return error_mark_node;
2732 : :
2733 : 3355070 : gcc_assert(TREE_CODE(type_tree) == TREE_CODE(TREE_TYPE(expr_tree)));
2734 : 3355070 : if (POINTER_TYPE_P(type_tree)
2735 : 3355070 : || INTEGRAL_TYPE_P(type_tree)
2736 : 233558 : || SCALAR_FLOAT_TYPE_P(type_tree)
2737 : 3588628 : || COMPLEX_FLOAT_TYPE_P(type_tree))
2738 : 3121514 : return fold_convert_loc(location.gcc_location(), type_tree, expr_tree);
2739 : 233556 : else if (TREE_CODE(type_tree) == RECORD_TYPE
2740 : 233556 : || TREE_CODE(type_tree) == ARRAY_TYPE)
2741 : : {
2742 : 233556 : gcc_assert(int_size_in_bytes(type_tree)
2743 : : == int_size_in_bytes(TREE_TYPE(expr_tree)));
2744 : 233556 : if (TYPE_MAIN_VARIANT(type_tree)
2745 : 233556 : == TYPE_MAIN_VARIANT(TREE_TYPE(expr_tree)))
2746 : 140587 : return fold_build1_loc(location.gcc_location(), NOP_EXPR,
2747 : 140587 : type_tree, expr_tree);
2748 : 92969 : return fold_build1_loc(location.gcc_location(), VIEW_CONVERT_EXPR,
2749 : 92969 : type_tree, expr_tree);
2750 : : }
2751 : :
2752 : 0 : gcc_unreachable();
2753 : : }
2754 : :
2755 : : // Make a global variable.
2756 : :
2757 : : Bvariable*
2758 : 34342 : Gcc_backend::global_variable(const std::string& var_name,
2759 : : const std::string& asm_name,
2760 : : Btype* btype,
2761 : : unsigned int flags,
2762 : : Location location)
2763 : : {
2764 : 34342 : tree type_tree = btype->get_tree();
2765 : 34342 : if (type_tree == error_mark_node)
2766 : 2 : return this->error_variable();
2767 : :
2768 : : // The GNU linker does not like dynamic variables with zero size.
2769 : 34340 : tree orig_type_tree = type_tree;
2770 : 34340 : bool is_external = (flags & variable_is_external) != 0;
2771 : 34340 : bool is_hidden = (flags & variable_is_hidden) != 0;
2772 : 34340 : if ((is_external || !is_hidden) && int_size_in_bytes(type_tree) == 0)
2773 : 410 : type_tree = this->non_zero_size_type(type_tree);
2774 : :
2775 : 34340 : tree decl = build_decl(location.gcc_location(), VAR_DECL,
2776 : : get_identifier_from_string(var_name),
2777 : : type_tree);
2778 : 34340 : if ((flags & variable_is_external) != 0)
2779 : : {
2780 : 9045 : DECL_EXTERNAL(decl) = 1;
2781 : 9045 : flags &=~ variable_is_external;
2782 : : }
2783 : : else
2784 : 25295 : TREE_STATIC(decl) = 1;
2785 : :
2786 : 34340 : if ((flags & variable_is_hidden) == 0)
2787 : 16416 : TREE_PUBLIC(decl) = 1;
2788 : : else
2789 : 17924 : flags &=~ variable_is_hidden;
2790 : :
2791 : 34340 : if ((flags & variable_address_is_taken) != 0)
2792 : : {
2793 : 3542 : TREE_ADDRESSABLE(decl) = 1;
2794 : 3542 : flags &=~ variable_address_is_taken;
2795 : : }
2796 : :
2797 : : // We take the address in Bvariable::get_tree if orig_type_tree is
2798 : : // different from type_tree.
2799 : 34340 : if (orig_type_tree != type_tree)
2800 : 410 : TREE_ADDRESSABLE(decl) = 1;
2801 : :
2802 : 34340 : SET_DECL_ASSEMBLER_NAME(decl, get_identifier_from_string(asm_name));
2803 : :
2804 : 34340 : TREE_USED(decl) = 1;
2805 : :
2806 : 34340 : if ((flags & variable_in_unique_section) != 0)
2807 : : {
2808 : 0 : resolve_unique_section (decl, 0, 1);
2809 : 0 : flags &=~ variable_in_unique_section;
2810 : : }
2811 : :
2812 : 34340 : gcc_assert(flags == 0);
2813 : :
2814 : 34340 : go_preserve_from_gc(decl);
2815 : :
2816 : 34340 : return new Bvariable(decl, orig_type_tree);
2817 : : }
2818 : :
2819 : : // Set the initial value of a global variable.
2820 : :
2821 : : void
2822 : 7290 : Gcc_backend::global_variable_set_init(Bvariable* var, Bexpression* expr)
2823 : : {
2824 : 7290 : tree expr_tree = expr->get_tree();
2825 : 7290 : if (expr_tree == error_mark_node)
2826 : : return;
2827 : 7290 : gcc_assert(TREE_CONSTANT(expr_tree));
2828 : 7290 : tree var_decl = var->get_decl();
2829 : 7290 : if (var_decl == error_mark_node)
2830 : : return;
2831 : 7290 : DECL_INITIAL(var_decl) = expr_tree;
2832 : :
2833 : : // If this variable goes in a unique section, it may need to go into
2834 : : // a different one now that DECL_INITIAL is set.
2835 : 7290 : if (symtab_node::get(var_decl)
2836 : 7290 : && symtab_node::get(var_decl)->implicit_section)
2837 : : {
2838 : 0 : set_decl_section_name (var_decl, (const char *) NULL);
2839 : 0 : resolve_unique_section (var_decl,
2840 : : compute_reloc_for_constant (expr_tree),
2841 : : 1);
2842 : : }
2843 : : }
2844 : :
2845 : : // Make a local variable.
2846 : :
2847 : : Bvariable*
2848 : 645188 : Gcc_backend::local_variable(Bfunction* function, const std::string& name,
2849 : : Btype* btype, Bvariable* decl_var,
2850 : : unsigned int flags, Location location)
2851 : : {
2852 : 645188 : tree type_tree = btype->get_tree();
2853 : 645188 : if (type_tree == error_mark_node)
2854 : 4 : return this->error_variable();
2855 : 645184 : tree decl = build_decl(location.gcc_location(), VAR_DECL,
2856 : : get_identifier_from_string(name),
2857 : : type_tree);
2858 : 645184 : DECL_CONTEXT(decl) = function->get_tree();
2859 : 645184 : TREE_USED(decl) = 1;
2860 : 645184 : if ((flags & variable_address_is_taken) != 0)
2861 : : {
2862 : 25283 : TREE_ADDRESSABLE(decl) = 1;
2863 : 25283 : flags &=~ variable_address_is_taken;
2864 : : }
2865 : 645184 : if (decl_var != NULL)
2866 : : {
2867 : 6520 : DECL_HAS_VALUE_EXPR_P(decl) = 1;
2868 : 6520 : SET_DECL_VALUE_EXPR(decl, decl_var->get_decl());
2869 : : }
2870 : 645184 : go_assert(flags == 0);
2871 : 645184 : go_preserve_from_gc(decl);
2872 : 645184 : return new Bvariable(decl);
2873 : : }
2874 : :
2875 : : // Make a function parameter variable.
2876 : :
2877 : : Bvariable*
2878 : 473832 : Gcc_backend::parameter_variable(Bfunction* function, const std::string& name,
2879 : : Btype* btype, unsigned int flags,
2880 : : Location location)
2881 : : {
2882 : 473832 : tree type_tree = btype->get_tree();
2883 : 473832 : if (type_tree == error_mark_node)
2884 : 6 : return this->error_variable();
2885 : 473826 : tree decl = build_decl(location.gcc_location(), PARM_DECL,
2886 : : get_identifier_from_string(name),
2887 : : type_tree);
2888 : 473826 : DECL_CONTEXT(decl) = function->get_tree();
2889 : 473826 : DECL_ARG_TYPE(decl) = type_tree;
2890 : 473826 : TREE_USED(decl) = 1;
2891 : 473826 : if ((flags & variable_address_is_taken) != 0)
2892 : : {
2893 : 8150 : TREE_ADDRESSABLE(decl) = 1;
2894 : 8150 : flags &=~ variable_address_is_taken;
2895 : : }
2896 : 473826 : go_assert(flags == 0);
2897 : 473826 : go_preserve_from_gc(decl);
2898 : 473826 : return new Bvariable(decl);
2899 : : }
2900 : :
2901 : : // Make a static chain variable.
2902 : :
2903 : : Bvariable*
2904 : 14291 : Gcc_backend::static_chain_variable(Bfunction* function, const std::string& name,
2905 : : Btype* btype, unsigned int flags,
2906 : : Location location)
2907 : : {
2908 : 14291 : tree type_tree = btype->get_tree();
2909 : 14291 : if (type_tree == error_mark_node)
2910 : 1 : return this->error_variable();
2911 : 14290 : tree decl = build_decl(location.gcc_location(), PARM_DECL,
2912 : : get_identifier_from_string(name), type_tree);
2913 : 14290 : tree fndecl = function->get_tree();
2914 : 14290 : DECL_CONTEXT(decl) = fndecl;
2915 : 14290 : DECL_ARG_TYPE(decl) = type_tree;
2916 : 14290 : TREE_USED(decl) = 1;
2917 : 14290 : DECL_ARTIFICIAL(decl) = 1;
2918 : 14290 : DECL_IGNORED_P(decl) = 1;
2919 : 14290 : DECL_NAMELESS(decl) = 1;
2920 : 14290 : TREE_READONLY(decl) = 1;
2921 : :
2922 : 14290 : struct function *f = DECL_STRUCT_FUNCTION(fndecl);
2923 : 14290 : if (f == NULL)
2924 : : {
2925 : 14290 : push_struct_function(fndecl);
2926 : 14290 : pop_cfun();
2927 : 14290 : f = DECL_STRUCT_FUNCTION(fndecl);
2928 : : }
2929 : 14290 : gcc_assert(f->static_chain_decl == NULL);
2930 : 14290 : f->static_chain_decl = decl;
2931 : 14290 : DECL_STATIC_CHAIN(fndecl) = 1;
2932 : 14290 : go_assert(flags == 0);
2933 : :
2934 : 14290 : go_preserve_from_gc(decl);
2935 : 14290 : return new Bvariable(decl);
2936 : : }
2937 : :
2938 : : // Make a temporary variable.
2939 : :
2940 : : Bvariable*
2941 : 2273183 : Gcc_backend::temporary_variable(Bfunction* function, Bblock* bblock,
2942 : : Btype* btype, Bexpression* binit,
2943 : : unsigned int flags,
2944 : : Location location,
2945 : : Bstatement** pstatement)
2946 : : {
2947 : 2273183 : gcc_assert(function != NULL);
2948 : 2273183 : tree decl = function->get_tree();
2949 : 2273183 : tree type_tree = btype->get_tree();
2950 : 2273183 : tree init_tree = binit == NULL ? NULL_TREE : binit->get_tree();
2951 : 2273183 : if (type_tree == error_mark_node
2952 : 2273182 : || init_tree == error_mark_node
2953 : 2273177 : || decl == error_mark_node)
2954 : : {
2955 : 6 : *pstatement = this->error_statement();
2956 : 6 : return this->error_variable();
2957 : : }
2958 : :
2959 : 2273177 : tree var;
2960 : : // We can only use create_tmp_var if the type is not addressable.
2961 : 2273177 : if (!TREE_ADDRESSABLE(type_tree))
2962 : : {
2963 : 2273177 : if (DECL_STRUCT_FUNCTION(decl) == NULL)
2964 : 230189 : push_struct_function(decl);
2965 : : else
2966 : 2042988 : push_cfun(DECL_STRUCT_FUNCTION(decl));
2967 : :
2968 : 2273177 : var = create_tmp_var(type_tree, "GOTMP");
2969 : 2273177 : pop_cfun();
2970 : : }
2971 : : else
2972 : : {
2973 : 0 : gcc_assert(bblock != NULL);
2974 : 0 : var = build_decl(location.gcc_location(), VAR_DECL,
2975 : : create_tmp_var_name("GOTMP"),
2976 : : type_tree);
2977 : 0 : DECL_ARTIFICIAL(var) = 1;
2978 : 0 : DECL_IGNORED_P(var) = 1;
2979 : 0 : DECL_NAMELESS(var) = 1;
2980 : 0 : TREE_USED(var) = 1;
2981 : 0 : DECL_CONTEXT(var) = decl;
2982 : :
2983 : : // We have to add this variable to the BLOCK and the BIND_EXPR.
2984 : 0 : tree bind_tree = bblock->get_tree();
2985 : 0 : gcc_assert(TREE_CODE(bind_tree) == BIND_EXPR);
2986 : 0 : tree block_tree = BIND_EXPR_BLOCK(bind_tree);
2987 : 0 : gcc_assert(TREE_CODE(block_tree) == BLOCK);
2988 : 0 : DECL_CHAIN(var) = BLOCK_VARS(block_tree);
2989 : 0 : BLOCK_VARS(block_tree) = var;
2990 : 0 : BIND_EXPR_VARS(bind_tree) = BLOCK_VARS(block_tree);
2991 : : }
2992 : :
2993 : 2273177 : if (this->type_size(btype) != 0
2994 : 2269618 : && init_tree != NULL_TREE
2995 : 4320751 : && TREE_TYPE(init_tree) != void_type_node)
2996 : 2047573 : DECL_INITIAL(var) = this->convert_tree(type_tree, init_tree, location);
2997 : :
2998 : 2273177 : if ((flags & variable_address_is_taken) != 0)
2999 : : {
3000 : 413098 : TREE_ADDRESSABLE(var) = 1;
3001 : 413098 : flags &=~ variable_address_is_taken;
3002 : : }
3003 : :
3004 : 2273177 : gcc_assert(flags == 0);
3005 : :
3006 : 2273177 : *pstatement = this->make_statement(build1_loc(location.gcc_location(),
3007 : : DECL_EXPR,
3008 : : void_type_node, var));
3009 : :
3010 : : // For a zero sized type, don't initialize VAR with BINIT, but still
3011 : : // evaluate BINIT for its side effects.
3012 : 2273177 : if (init_tree != NULL_TREE
3013 : 2273177 : && (this->type_size(btype) == 0
3014 : 2047574 : || TREE_TYPE(init_tree) == void_type_node))
3015 : 1372 : *pstatement =
3016 : 1372 : this->compound_statement(this->expression_statement(function, binit),
3017 : : *pstatement);
3018 : :
3019 : 2273177 : return new Bvariable(var);
3020 : : }
3021 : :
3022 : : // Create an implicit variable that is compiler-defined. This is used when
3023 : : // generating GC root variables and storing the values of a slice initializer.
3024 : :
3025 : : Bvariable*
3026 : 334144 : Gcc_backend::implicit_variable(const std::string& name,
3027 : : const std::string& asm_name,
3028 : : Btype* type, unsigned int flags,
3029 : : int64_t alignment)
3030 : : {
3031 : 334144 : tree type_tree = type->get_tree();
3032 : 334144 : if (type_tree == error_mark_node)
3033 : 0 : return this->error_variable();
3034 : :
3035 : 334144 : tree decl = build_decl(BUILTINS_LOCATION, VAR_DECL,
3036 : : get_identifier_from_string(name), type_tree);
3037 : 334144 : DECL_EXTERNAL(decl) = 0;
3038 : 334144 : if ((flags & variable_is_hidden) != 0)
3039 : 305868 : flags &=~ variable_is_hidden;
3040 : : else
3041 : 28276 : TREE_PUBLIC(decl) = 1;
3042 : 334144 : TREE_STATIC(decl) = 1;
3043 : 334144 : TREE_USED(decl) = 1;
3044 : 334144 : DECL_ARTIFICIAL(decl) = 1;
3045 : 334144 : if ((flags & variable_is_common) != 0)
3046 : : {
3047 : 23630 : DECL_COMMON(decl) = 1;
3048 : :
3049 : : // When the initializer for one implicit_variable refers to another,
3050 : : // it needs to know the visibility of the referenced struct so that
3051 : : // compute_reloc_for_constant will return the right value. On many
3052 : : // systems calling make_decl_one_only will mark the decl as weak,
3053 : : // which will change the return value of compute_reloc_for_constant.
3054 : : // We can't reliably call make_decl_one_only yet, because we don't
3055 : : // yet know the initializer. This issue doesn't arise in C because
3056 : : // Go initializers, unlike C initializers, can be indirectly
3057 : : // recursive. To ensure that compute_reloc_for_constant computes
3058 : : // the right value if some other initializer refers to this one, we
3059 : : // mark this symbol as weak here. We undo that below in
3060 : : // immutable_struct_set_init before calling mark_decl_one_only.
3061 : 23630 : DECL_WEAK(decl) = 1;
3062 : :
3063 : 23630 : flags &=~ variable_is_common;
3064 : : }
3065 : 334144 : if ((flags & variable_is_constant) != 0)
3066 : : {
3067 : 323167 : TREE_READONLY(decl) = 1;
3068 : 323167 : TREE_CONSTANT(decl) = 1;
3069 : 323167 : flags &=~ variable_is_constant;
3070 : : }
3071 : 334144 : if ((flags & variable_address_is_taken) != 0)
3072 : : {
3073 : 303945 : TREE_ADDRESSABLE(decl) = 1;
3074 : 303945 : flags &=~ variable_address_is_taken;
3075 : : }
3076 : 334144 : if (alignment != 0)
3077 : : {
3078 : 3 : SET_DECL_ALIGN(decl, alignment * BITS_PER_UNIT);
3079 : 3 : DECL_USER_ALIGN(decl) = 1;
3080 : : }
3081 : 334144 : if (! asm_name.empty())
3082 : 6535 : SET_DECL_ASSEMBLER_NAME(decl, get_identifier_from_string(asm_name));
3083 : 334144 : gcc_assert(flags == 0);
3084 : :
3085 : 334144 : go_preserve_from_gc(decl);
3086 : 334144 : return new Bvariable(decl);
3087 : : }
3088 : :
3089 : : // Set the initalizer for a variable created by implicit_variable.
3090 : : // This is where we finish compiling the variable.
3091 : :
3092 : : void
3093 : 334144 : Gcc_backend::implicit_variable_set_init(Bvariable* var, const std::string&,
3094 : : Btype*, unsigned int flags,
3095 : : Bexpression* init)
3096 : : {
3097 : 334144 : tree decl = var->get_decl();
3098 : 334144 : tree init_tree;
3099 : 334144 : if (init == NULL)
3100 : : init_tree = NULL_TREE;
3101 : : else
3102 : 334141 : init_tree = init->get_tree();
3103 : 334144 : if (decl == error_mark_node || init_tree == error_mark_node)
3104 : : return;
3105 : :
3106 : 334142 : DECL_INITIAL(decl) = init_tree;
3107 : :
3108 : : // Now that DECL_INITIAL is set, we can't call make_decl_one_only.
3109 : : // See the comment where DECL_WEAK is set in implicit_variable.
3110 : 334142 : if ((flags & variable_is_common) != 0)
3111 : : {
3112 : 23630 : DECL_WEAK(decl) = 0;
3113 : 23630 : make_decl_one_only(decl, DECL_ASSEMBLER_NAME(decl));
3114 : : }
3115 : :
3116 : 334142 : resolve_unique_section(decl, 2, 1);
3117 : :
3118 : 334142 : rest_of_decl_compilation(decl, 1, 0);
3119 : : }
3120 : :
3121 : : // Return a reference to an implicit variable defined in another package.
3122 : :
3123 : : Bvariable*
3124 : 64317 : Gcc_backend::implicit_variable_reference(const std::string& name,
3125 : : const std::string& asm_name,
3126 : : Btype* btype)
3127 : : {
3128 : 64317 : tree type_tree = btype->get_tree();
3129 : 64317 : if (type_tree == error_mark_node)
3130 : 0 : return this->error_variable();
3131 : :
3132 : 64317 : tree decl = build_decl(BUILTINS_LOCATION, VAR_DECL,
3133 : : get_identifier_from_string(name), type_tree);
3134 : 64317 : DECL_EXTERNAL(decl) = 1;
3135 : 64317 : TREE_PUBLIC(decl) = 1;
3136 : 64317 : TREE_STATIC(decl) = 0;
3137 : 64317 : DECL_ARTIFICIAL(decl) = 1;
3138 : 64317 : if (! asm_name.empty())
3139 : 64317 : SET_DECL_ASSEMBLER_NAME(decl, get_identifier_from_string(asm_name));
3140 : 64317 : go_preserve_from_gc(decl);
3141 : 64317 : return new Bvariable(decl);
3142 : : }
3143 : :
3144 : : // Create a named immutable initialized data structure.
3145 : :
3146 : : Bvariable*
3147 : 1128308 : Gcc_backend::immutable_struct(const std::string& name,
3148 : : const std::string& asm_name,
3149 : : unsigned int flags, Btype* btype,
3150 : : Location location)
3151 : : {
3152 : 1128308 : tree type_tree = btype->get_tree();
3153 : 1128308 : if (type_tree == error_mark_node)
3154 : 5 : return this->error_variable();
3155 : 1128303 : gcc_assert(TREE_CODE(type_tree) == RECORD_TYPE);
3156 : 1128303 : tree decl = build_decl(location.gcc_location(), VAR_DECL,
3157 : : get_identifier_from_string(name),
3158 : : build_qualified_type(type_tree, TYPE_QUAL_CONST));
3159 : 1128303 : TREE_STATIC(decl) = 1;
3160 : 1128303 : TREE_USED(decl) = 1;
3161 : 1128303 : TREE_READONLY(decl) = 1;
3162 : 1128303 : TREE_CONSTANT(decl) = 1;
3163 : 1128303 : DECL_ARTIFICIAL(decl) = 1;
3164 : 1128303 : if ((flags & variable_is_hidden) != 0)
3165 : 753750 : flags &=~ variable_is_hidden;
3166 : : else
3167 : 374553 : TREE_PUBLIC(decl) = 1;
3168 : 1128303 : if (! asm_name.empty())
3169 : 242381 : SET_DECL_ASSEMBLER_NAME(decl, get_identifier_from_string(asm_name));
3170 : 1128303 : if ((flags & variable_address_is_taken) != 0)
3171 : : {
3172 : 706919 : TREE_ADDRESSABLE(decl) = 1;
3173 : 706919 : flags &=~ variable_address_is_taken;
3174 : : }
3175 : :
3176 : : // When the initializer for one immutable_struct refers to another,
3177 : : // it needs to know the visibility of the referenced struct so that
3178 : : // compute_reloc_for_constant will return the right value. On many
3179 : : // systems calling make_decl_one_only will mark the decl as weak,
3180 : : // which will change the return value of compute_reloc_for_constant.
3181 : : // We can't reliably call make_decl_one_only yet, because we don't
3182 : : // yet know the initializer. This issue doesn't arise in C because
3183 : : // Go initializers, unlike C initializers, can be indirectly
3184 : : // recursive. To ensure that compute_reloc_for_constant computes
3185 : : // the right value if some other initializer refers to this one, we
3186 : : // mark this symbol as weak here. We undo that below in
3187 : : // immutable_struct_set_init before calling mark_decl_one_only.
3188 : 1128303 : if ((flags & variable_is_common) != 0)
3189 : : {
3190 : 215169 : DECL_WEAK(decl) = 1;
3191 : 215169 : flags &=~ variable_is_common;
3192 : : }
3193 : :
3194 : 1128303 : gcc_assert(flags == 0);
3195 : :
3196 : : // We don't call rest_of_decl_compilation until we have the
3197 : : // initializer.
3198 : :
3199 : 1128303 : go_preserve_from_gc(decl);
3200 : 1128303 : return new Bvariable(decl);
3201 : : }
3202 : :
3203 : : // Set the initializer for a variable created by immutable_struct.
3204 : : // This is where we finish compiling the variable.
3205 : :
3206 : : void
3207 : 1128308 : Gcc_backend::immutable_struct_set_init(Bvariable* var, const std::string&,
3208 : : unsigned int flags, Btype*, Location,
3209 : : Bexpression* initializer)
3210 : : {
3211 : 1128308 : tree decl = var->get_decl();
3212 : 1128308 : tree init_tree = initializer->get_tree();
3213 : 1128308 : if (decl == error_mark_node || init_tree == error_mark_node)
3214 : : return;
3215 : :
3216 : 1128302 : DECL_INITIAL(decl) = init_tree;
3217 : :
3218 : : // Now that DECL_INITIAL is set, we can't call make_decl_one_only.
3219 : : // See the comment where DECL_WEAK is set in immutable_struct.
3220 : 1128302 : if ((flags & variable_is_common) != 0)
3221 : : {
3222 : 215168 : DECL_WEAK(decl) = 0;
3223 : 215168 : make_decl_one_only(decl, DECL_ASSEMBLER_NAME(decl));
3224 : : }
3225 : :
3226 : : // These variables are often unneeded in the final program, so put
3227 : : // them in their own section so that linker GC can discard them.
3228 : 1128302 : resolve_unique_section(decl,
3229 : : compute_reloc_for_constant (init_tree),
3230 : : 1);
3231 : :
3232 : 1128302 : rest_of_decl_compilation(decl, 1, 0);
3233 : : }
3234 : :
3235 : : // Return a reference to an immutable initialized data structure
3236 : : // defined in another package.
3237 : :
3238 : : Bvariable*
3239 : 188916 : Gcc_backend::immutable_struct_reference(const std::string& name,
3240 : : const std::string& asm_name,
3241 : : Btype* btype,
3242 : : Location location)
3243 : : {
3244 : 188916 : tree type_tree = btype->get_tree();
3245 : 188916 : if (type_tree == error_mark_node)
3246 : 0 : return this->error_variable();
3247 : 188916 : gcc_assert(TREE_CODE(type_tree) == RECORD_TYPE);
3248 : 188916 : tree decl = build_decl(location.gcc_location(), VAR_DECL,
3249 : : get_identifier_from_string(name),
3250 : : build_qualified_type(type_tree, TYPE_QUAL_CONST));
3251 : 188916 : TREE_READONLY(decl) = 1;
3252 : 188916 : TREE_CONSTANT(decl) = 1;
3253 : 188916 : DECL_ARTIFICIAL(decl) = 1;
3254 : 188916 : TREE_PUBLIC(decl) = 1;
3255 : 188916 : DECL_EXTERNAL(decl) = 1;
3256 : 188916 : if (! asm_name.empty())
3257 : 34530 : SET_DECL_ASSEMBLER_NAME(decl, get_identifier_from_string(asm_name));
3258 : 188916 : go_preserve_from_gc(decl);
3259 : 188916 : return new Bvariable(decl);
3260 : : }
3261 : :
3262 : : // Make a label.
3263 : :
3264 : : Blabel*
3265 : 193164 : Gcc_backend::label(Bfunction* function, const std::string& name,
3266 : : Location location)
3267 : : {
3268 : 193164 : tree decl;
3269 : 193164 : if (name.empty())
3270 : : {
3271 : 182752 : tree func_tree = function->get_tree();
3272 : 182752 : if (DECL_STRUCT_FUNCTION(func_tree) == NULL)
3273 : 8399 : push_struct_function(func_tree);
3274 : : else
3275 : 174353 : push_cfun(DECL_STRUCT_FUNCTION(func_tree));
3276 : :
3277 : 182752 : decl = create_artificial_label(location.gcc_location());
3278 : :
3279 : 182752 : pop_cfun();
3280 : : }
3281 : : else
3282 : : {
3283 : 10412 : tree id = get_identifier_from_string(name);
3284 : 10412 : decl = build_decl(location.gcc_location(), LABEL_DECL, id,
3285 : : void_type_node);
3286 : 10412 : DECL_CONTEXT(decl) = function->get_tree();
3287 : : }
3288 : 193164 : return new Blabel(decl);
3289 : : }
3290 : :
3291 : : // Make a statement which defines a label.
3292 : :
3293 : : Bstatement*
3294 : 193164 : Gcc_backend::label_definition_statement(Blabel* label)
3295 : : {
3296 : 193164 : tree lab = label->get_tree();
3297 : 193164 : tree ret = fold_build1_loc(DECL_SOURCE_LOCATION(lab), LABEL_EXPR,
3298 : : void_type_node, lab);
3299 : 193164 : return this->make_statement(ret);
3300 : : }
3301 : :
3302 : : // Make a goto statement.
3303 : :
3304 : : Bstatement*
3305 : 242991 : Gcc_backend::goto_statement(Blabel* label, Location location)
3306 : : {
3307 : 242991 : tree lab = label->get_tree();
3308 : 242991 : tree ret = fold_build1_loc(location.gcc_location(), GOTO_EXPR, void_type_node,
3309 : : lab);
3310 : 242991 : return this->make_statement(ret);
3311 : : }
3312 : :
3313 : : // Get the address of a label.
3314 : :
3315 : : Bexpression*
3316 : 8840 : Gcc_backend::label_address(Blabel* label, Location location)
3317 : : {
3318 : 8840 : tree lab = label->get_tree();
3319 : 8840 : TREE_USED(lab) = 1;
3320 : 8840 : TREE_ADDRESSABLE(lab) = 1;
3321 : 8840 : tree ret = fold_convert_loc(location.gcc_location(), ptr_type_node,
3322 : : build_fold_addr_expr_loc(location.gcc_location(),
3323 : : lab));
3324 : 8840 : return this->make_expression(ret);
3325 : : }
3326 : :
3327 : : // Declare or define a new function.
3328 : :
3329 : : Bfunction*
3330 : 611098 : Gcc_backend::function(Btype* fntype, const std::string& name,
3331 : : const std::string& asm_name, unsigned int flags,
3332 : : Location location)
3333 : : {
3334 : 611098 : tree functype = fntype->get_tree();
3335 : 611098 : if (functype != error_mark_node)
3336 : : {
3337 : 611084 : gcc_assert(FUNCTION_POINTER_TYPE_P(functype));
3338 : 611084 : functype = TREE_TYPE(functype);
3339 : : }
3340 : 611098 : tree id = get_identifier_from_string(name);
3341 : 611098 : if (functype == error_mark_node || id == error_mark_node)
3342 : 14 : return this->error_function();
3343 : :
3344 : 611084 : tree decl = build_decl(location.gcc_location(), FUNCTION_DECL, id, functype);
3345 : 611084 : if (! asm_name.empty())
3346 : 223760 : SET_DECL_ASSEMBLER_NAME(decl, get_identifier_from_string(asm_name));
3347 : 611084 : if ((flags & function_is_visible) != 0)
3348 : 527851 : TREE_PUBLIC(decl) = 1;
3349 : 611084 : if ((flags & function_is_declaration) != 0)
3350 : 312315 : DECL_EXTERNAL(decl) = 1;
3351 : : else
3352 : : {
3353 : 298769 : tree restype = TREE_TYPE(functype);
3354 : 298769 : tree resdecl =
3355 : 298769 : build_decl(location.gcc_location(), RESULT_DECL, NULL_TREE, restype);
3356 : 298769 : DECL_ARTIFICIAL(resdecl) = 1;
3357 : 298769 : DECL_IGNORED_P(resdecl) = 1;
3358 : 298769 : DECL_NAMELESS(resdecl) = 1;
3359 : 298769 : DECL_CONTEXT(resdecl) = decl;
3360 : 298769 : DECL_RESULT(decl) = resdecl;
3361 : : }
3362 : 611084 : if ((flags & function_is_inlinable) == 0)
3363 : 10863 : DECL_UNINLINABLE(decl) = 1;
3364 : 611084 : if ((flags & function_no_split_stack) != 0)
3365 : : {
3366 : 2264 : tree attr = get_identifier ("no_split_stack");
3367 : 2264 : DECL_ATTRIBUTES(decl) = tree_cons(attr, NULL_TREE, NULL_TREE);
3368 : : }
3369 : 611084 : if ((flags & function_does_not_return) != 0)
3370 : 16108 : TREE_THIS_VOLATILE(decl) = 1;
3371 : 611084 : if ((flags & function_in_unique_section) != 0)
3372 : 3 : resolve_unique_section(decl, 0, 1);
3373 : 611084 : if ((flags & function_only_inline) != 0)
3374 : : {
3375 : 12247 : TREE_PUBLIC (decl) = 1;
3376 : 12247 : DECL_EXTERNAL(decl) = 1;
3377 : 12247 : DECL_DECLARED_INLINE_P(decl) = 1;
3378 : : }
3379 : :
3380 : : // Optimize thunk functions for size. A thunk created for a defer
3381 : : // statement that may call recover looks like:
3382 : : // if runtime.setdeferretaddr(L1) {
3383 : : // goto L1
3384 : : // }
3385 : : // realfn()
3386 : : // L1:
3387 : : // The idea is that L1 should be the address to which realfn
3388 : : // returns. This only works if this little function is not over
3389 : : // optimized. At some point GCC started duplicating the epilogue in
3390 : : // the basic-block reordering pass, breaking this assumption.
3391 : : // Optimizing the function for size avoids duplicating the epilogue.
3392 : : // This optimization shouldn't matter for any thunk since all thunks
3393 : : // are small.
3394 : 611084 : size_t pos = name.find("..thunk");
3395 : 611084 : if (pos != std::string::npos)
3396 : : {
3397 : 44954 : for (pos += 7; pos < name.length(); ++pos)
3398 : : {
3399 : 30007 : if (name[pos] < '0' || name[pos] > '9')
3400 : : break;
3401 : : }
3402 : 14947 : if (pos == name.length())
3403 : : {
3404 : 14947 : struct cl_optimization cur_opts;
3405 : 14947 : cl_optimization_save(&cur_opts, &global_options,
3406 : : &global_options_set);
3407 : 14947 : global_options.x_optimize_size = 1;
3408 : 14947 : global_options.x_optimize_fast = 0;
3409 : 14947 : global_options.x_optimize_debug = 0;
3410 : 29894 : DECL_FUNCTION_SPECIFIC_OPTIMIZATION(decl) =
3411 : 14947 : build_optimization_node(&global_options, &global_options_set);
3412 : 14947 : cl_optimization_restore(&global_options, &global_options_set,
3413 : : &cur_opts);
3414 : : }
3415 : : }
3416 : :
3417 : 611084 : go_preserve_from_gc(decl);
3418 : 611084 : return new Bfunction(decl);
3419 : : }
3420 : :
3421 : : // Create a statement that runs all deferred calls for FUNCTION. This should
3422 : : // be a statement that looks like this in C++:
3423 : : // finish:
3424 : : // try { UNDEFER; } catch { CHECK_DEFER; goto finish; }
3425 : :
3426 : : Bstatement*
3427 : 8353 : Gcc_backend::function_defer_statement(Bfunction* function, Bexpression* undefer,
3428 : : Bexpression* defer, Location location)
3429 : : {
3430 : 8353 : tree undefer_tree = undefer->get_tree();
3431 : 8353 : tree defer_tree = defer->get_tree();
3432 : 8353 : tree fntree = function->get_tree();
3433 : :
3434 : 8353 : if (undefer_tree == error_mark_node
3435 : 8353 : || defer_tree == error_mark_node
3436 : 8353 : || fntree == error_mark_node)
3437 : 0 : return this->error_statement();
3438 : :
3439 : 8353 : if (DECL_STRUCT_FUNCTION(fntree) == NULL)
3440 : 0 : push_struct_function(fntree);
3441 : : else
3442 : 8353 : push_cfun(DECL_STRUCT_FUNCTION(fntree));
3443 : :
3444 : 8353 : tree stmt_list = NULL;
3445 : 8353 : Blabel* blabel = this->label(function, "", location);
3446 : 8353 : Bstatement* label_def = this->label_definition_statement(blabel);
3447 : 8353 : append_to_statement_list(label_def->get_tree(), &stmt_list);
3448 : :
3449 : 8353 : Bstatement* jump_stmt = this->goto_statement(blabel, location);
3450 : 8353 : tree jump = jump_stmt->get_tree();
3451 : 8353 : tree catch_body = build2(COMPOUND_EXPR, void_type_node, defer_tree, jump);
3452 : 8353 : catch_body = build2(CATCH_EXPR, void_type_node, NULL, catch_body);
3453 : 8353 : tree try_catch =
3454 : 8353 : build2(TRY_CATCH_EXPR, void_type_node, undefer_tree, catch_body);
3455 : 8353 : append_to_statement_list(try_catch, &stmt_list);
3456 : 8353 : pop_cfun();
3457 : :
3458 : 8353 : return this->make_statement(stmt_list);
3459 : : }
3460 : :
3461 : : // Record PARAM_VARS as the variables to use for the parameters of FUNCTION.
3462 : : // This will only be called for a function definition.
3463 : :
3464 : : bool
3465 : 295330 : Gcc_backend::function_set_parameters(Bfunction* function,
3466 : : const std::vector<Bvariable*>& param_vars)
3467 : : {
3468 : 295330 : tree func_tree = function->get_tree();
3469 : 295330 : if (func_tree == error_mark_node)
3470 : : return false;
3471 : :
3472 : 295316 : tree params = NULL_TREE;
3473 : 295316 : tree *pp = ¶ms;
3474 : 295316 : for (std::vector<Bvariable*>::const_iterator pv = param_vars.begin();
3475 : 769139 : pv != param_vars.end();
3476 : 473823 : ++pv)
3477 : : {
3478 : 473823 : *pp = (*pv)->get_decl();
3479 : 473823 : gcc_assert(*pp != error_mark_node);
3480 : 473823 : pp = &DECL_CHAIN(*pp);
3481 : : }
3482 : 295316 : *pp = NULL_TREE;
3483 : 295316 : DECL_ARGUMENTS(func_tree) = params;
3484 : 295316 : return true;
3485 : : }
3486 : :
3487 : : // Set the function body for FUNCTION using the code in CODE_BLOCK.
3488 : :
3489 : : bool
3490 : 298765 : Gcc_backend::function_set_body(Bfunction* function, Bstatement* code_stmt)
3491 : : {
3492 : 298765 : tree func_tree = function->get_tree();
3493 : 298765 : tree code = code_stmt->get_tree();
3494 : :
3495 : 298765 : if (func_tree == error_mark_node || code == error_mark_node)
3496 : : return false;
3497 : 298724 : DECL_SAVED_TREE(func_tree) = code;
3498 : 298724 : return true;
3499 : : }
3500 : :
3501 : : // Look up a named built-in function in the current backend implementation.
3502 : : // Returns NULL if no built-in function by that name exists.
3503 : :
3504 : : Bfunction*
3505 : 130081 : Gcc_backend::lookup_builtin(const std::string& name)
3506 : : {
3507 : 130081 : if (this->builtin_functions_.count(name) != 0)
3508 : 5835 : return this->builtin_functions_[name];
3509 : : return NULL;
3510 : : }
3511 : :
3512 : : // Write the definitions for all TYPE_DECLS, CONSTANT_DECLS,
3513 : : // FUNCTION_DECLS, and VARIABLE_DECLS declared globally, as well as
3514 : : // emit early debugging information.
3515 : :
3516 : : void
3517 : 4217 : Gcc_backend::write_global_definitions(
3518 : : const std::vector<Btype*>& type_decls,
3519 : : const std::vector<Bexpression*>& constant_decls,
3520 : : const std::vector<Bfunction*>& function_decls,
3521 : : const std::vector<Bvariable*>& variable_decls)
3522 : : {
3523 : 4217 : size_t count_definitions = type_decls.size() + constant_decls.size()
3524 : 4217 : + function_decls.size() + variable_decls.size();
3525 : :
3526 : 4217 : tree* defs = new tree[count_definitions];
3527 : :
3528 : : // Convert all non-erroneous declarations into Gimple form.
3529 : 4217 : size_t i = 0;
3530 : 28705 : for (std::vector<Bvariable*>::const_iterator p = variable_decls.begin();
3531 : 28705 : p != variable_decls.end();
3532 : 24488 : ++p)
3533 : : {
3534 : 24488 : tree v = (*p)->get_decl();
3535 : 24488 : if (v != error_mark_node)
3536 : : {
3537 : 24488 : defs[i] = v;
3538 : 24488 : go_preserve_from_gc(defs[i]);
3539 : 24488 : ++i;
3540 : : }
3541 : : }
3542 : :
3543 : 33757 : for (std::vector<Btype*>::const_iterator p = type_decls.begin();
3544 : 33757 : p != type_decls.end();
3545 : 29540 : ++p)
3546 : : {
3547 : 29540 : tree type_tree = (*p)->get_tree();
3548 : 29540 : if (type_tree != error_mark_node
3549 : 29540 : && IS_TYPE_OR_DECL_P(type_tree))
3550 : : {
3551 : 29540 : defs[i] = TYPE_NAME(type_tree);
3552 : 29540 : gcc_assert(defs[i] != NULL);
3553 : 29540 : go_preserve_from_gc(defs[i]);
3554 : 29540 : ++i;
3555 : : }
3556 : : }
3557 : 27550 : for (std::vector<Bexpression*>::const_iterator p = constant_decls.begin();
3558 : 27550 : p != constant_decls.end();
3559 : 23333 : ++p)
3560 : : {
3561 : 23333 : if ((*p)->get_tree() != error_mark_node)
3562 : : {
3563 : 23333 : defs[i] = (*p)->get_tree();
3564 : 23333 : go_preserve_from_gc(defs[i]);
3565 : 23333 : ++i;
3566 : : }
3567 : : }
3568 : 294575 : for (std::vector<Bfunction*>::const_iterator p = function_decls.begin();
3569 : 294575 : p != function_decls.end();
3570 : 290358 : ++p)
3571 : : {
3572 : 290358 : tree decl = (*p)->get_tree();
3573 : 290358 : if (decl != error_mark_node)
3574 : : {
3575 : 290358 : go_preserve_from_gc(decl);
3576 : 290358 : if (DECL_STRUCT_FUNCTION(decl) == NULL)
3577 : 44364 : allocate_struct_function(decl, false);
3578 : 290358 : cgraph_node::finalize_function(decl, true);
3579 : :
3580 : 290358 : defs[i] = decl;
3581 : 290358 : ++i;
3582 : : }
3583 : : }
3584 : :
3585 : : // Pass everything back to the middle-end.
3586 : :
3587 : 4217 : wrapup_global_declarations(defs, i);
3588 : :
3589 : 4217 : delete[] defs;
3590 : 4217 : }
3591 : :
3592 : : void
3593 : 7157406 : Gcc_backend::write_export_data(const char* bytes, unsigned int size)
3594 : : {
3595 : 7157406 : go_write_export_data(bytes, size);
3596 : 7157406 : }
3597 : :
3598 : :
3599 : : // Define a builtin function. BCODE is the builtin function code
3600 : : // defined by builtins.def. NAME is the name of the builtin function.
3601 : : // LIBNAME is the name of the corresponding library function, and is
3602 : : // NULL if there isn't one. FNTYPE is the type of the function.
3603 : : // FLAGS are the attributes to add, a bitset of builtin_xxx consts.
3604 : :
3605 : : void
3606 : 385618 : Gcc_backend::define_builtin(built_in_function bcode, const char* name,
3607 : : const char* libname, tree fntype, int flags)
3608 : : {
3609 : 385618 : tree decl = add_builtin_function(name, fntype, bcode, BUILT_IN_NORMAL,
3610 : : libname, NULL_TREE);
3611 : 385618 : this->set_attributes(decl, flags);
3612 : 385618 : set_builtin_decl(bcode, decl, true);
3613 : 385618 : this->builtin_functions_[name] = this->make_function(decl);
3614 : 385618 : if (libname != NULL)
3615 : : {
3616 : 250884 : decl = add_builtin_function(libname, fntype, bcode, BUILT_IN_NORMAL,
3617 : : NULL, NULL_TREE);
3618 : 250884 : this->set_attributes(decl, flags);
3619 : 250884 : this->builtin_functions_[libname] = this->make_function(decl);
3620 : : }
3621 : 385618 : }
3622 : :
3623 : : // Set the attributes of DECL based on FLAGS.
3624 : :
3625 : : void
3626 : 636502 : Gcc_backend::set_attributes(tree decl, int flags)
3627 : : {
3628 : 636502 : if ((flags & builtin_const) != 0)
3629 : 483184 : TREE_READONLY(decl) = 1;
3630 : 636502 : if ((flags & builtin_pure) != 0)
3631 : 9292 : DECL_PURE_P(decl) = 1;
3632 : 636502 : if ((flags & builtin_nothrow) != 0)
3633 : 144026 : TREE_NOTHROW (decl) = 1;
3634 : 636502 : if ((flags & builtin_noreturn) != 0)
3635 : 9292 : TREE_THIS_VOLATILE(decl) = 1;
3636 : 636502 : if ((flags & builtin_novops) != 0)
3637 : 4646 : DECL_IS_NOVOPS(decl) = 1;
3638 : 636502 : if ((flags & builtin_leaf) != 0)
3639 : 232300 : DECL_ATTRIBUTES(decl) = tree_cons(get_identifier("leaf"), NULL_TREE,
3640 : 232300 : DECL_ATTRIBUTES(decl));
3641 : 636502 : if ((flags & builtin_nonnull) != 0)
3642 : 27876 : DECL_ATTRIBUTES(decl) = tree_cons(get_identifier("nonnull"), NULL_TREE,
3643 : 27876 : DECL_ATTRIBUTES(decl));
3644 : 636502 : if ((flags & builtin_cold) != 0)
3645 : 9292 : DECL_ATTRIBUTES(decl) = tree_cons(get_identifier("cold"), NULL_TREE,
3646 : 9292 : DECL_ATTRIBUTES(decl));
3647 : 636502 : }
3648 : :
3649 : : // Return the backend generator.
3650 : :
3651 : : Backend*
3652 : 4646 : go_get_backend()
3653 : : {
3654 : 4646 : return new Gcc_backend();
3655 : : }
|