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