163d1a8abSmrg /* Language-dependent hooks for LTO.
2*ec02198aSmrg    Copyright (C) 2009-2020 Free Software Foundation, Inc.
363d1a8abSmrg    Contributed by CodeSourcery, Inc.
463d1a8abSmrg 
563d1a8abSmrg This file is part of GCC.
663d1a8abSmrg 
763d1a8abSmrg GCC is free software; you can redistribute it and/or modify it under
863d1a8abSmrg the terms of the GNU General Public License as published by the Free
963d1a8abSmrg Software Foundation; either version 3, or (at your option) any later
1063d1a8abSmrg version.
1163d1a8abSmrg 
1263d1a8abSmrg GCC is distributed in the hope that it will be useful, but WITHOUT ANY
1363d1a8abSmrg WARRANTY; without even the implied warranty of MERCHANTABILITY or
1463d1a8abSmrg FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
1563d1a8abSmrg for more details.
1663d1a8abSmrg 
1763d1a8abSmrg You should have received a copy of the GNU General Public License
1863d1a8abSmrg along with GCC; see the file COPYING3.  If not see
1963d1a8abSmrg <http://www.gnu.org/licenses/>.  */
2063d1a8abSmrg 
2163d1a8abSmrg #include "config.h"
2263d1a8abSmrg #include "system.h"
2363d1a8abSmrg #include "coretypes.h"
2463d1a8abSmrg #include "target.h"
2563d1a8abSmrg #include "function.h"
2663d1a8abSmrg #include "basic-block.h"
2763d1a8abSmrg #include "tree.h"
2863d1a8abSmrg #include "gimple.h"
2963d1a8abSmrg #include "stringpool.h"
3063d1a8abSmrg #include "diagnostic-core.h"
3163d1a8abSmrg #include "stor-layout.h"
3263d1a8abSmrg #include "langhooks.h"
3363d1a8abSmrg #include "langhooks-def.h"
3463d1a8abSmrg #include "debug.h"
3563d1a8abSmrg #include "lto-tree.h"
3663d1a8abSmrg #include "lto.h"
37*ec02198aSmrg #include "lto-common.h"
38c7a68eb7Smrg #include "stringpool.h"
39c7a68eb7Smrg #include "attribs.h"
4063d1a8abSmrg 
410fc04c29Smrg /* LTO specific dumps.  */
420fc04c29Smrg int lto_link_dump_id, decl_merge_dump_id, partition_dump_id;
430fc04c29Smrg 
4463d1a8abSmrg static tree handle_noreturn_attribute (tree *, tree, tree, int, bool *);
4563d1a8abSmrg static tree handle_leaf_attribute (tree *, tree, tree, int, bool *);
4663d1a8abSmrg static tree handle_const_attribute (tree *, tree, tree, int, bool *);
4763d1a8abSmrg static tree handle_malloc_attribute (tree *, tree, tree, int, bool *);
4863d1a8abSmrg static tree handle_pure_attribute (tree *, tree, tree, int, bool *);
4963d1a8abSmrg static tree handle_novops_attribute (tree *, tree, tree, int, bool *);
5063d1a8abSmrg static tree handle_nonnull_attribute (tree *, tree, tree, int, bool *);
5163d1a8abSmrg static tree handle_nothrow_attribute (tree *, tree, tree, int, bool *);
5263d1a8abSmrg static tree handle_sentinel_attribute (tree *, tree, tree, int, bool *);
5363d1a8abSmrg static tree handle_type_generic_attribute (tree *, tree, tree, int, bool *);
5463d1a8abSmrg static tree handle_transaction_pure_attribute (tree *, tree, tree, int, bool *);
5563d1a8abSmrg static tree handle_returns_twice_attribute (tree *, tree, tree, int, bool *);
56c7a68eb7Smrg static tree handle_patchable_function_entry_attribute (tree *, tree, tree,
57c7a68eb7Smrg 						       int, bool *);
5863d1a8abSmrg static tree ignore_attribute (tree *, tree, tree, int, bool *);
5963d1a8abSmrg 
6063d1a8abSmrg static tree handle_format_attribute (tree *, tree, tree, int, bool *);
6163d1a8abSmrg static tree handle_fnspec_attribute (tree *, tree, tree, int, bool *);
6263d1a8abSmrg static tree handle_format_arg_attribute (tree *, tree, tree, int, bool *);
6363d1a8abSmrg 
64c7a68eb7Smrg /* Helper to define attribute exclusions.  */
65c7a68eb7Smrg #define ATTR_EXCL(name, function, type, variable)	\
66c7a68eb7Smrg   { name, function, type, variable }
67c7a68eb7Smrg 
68c7a68eb7Smrg /* Define attributes that are mutually exclusive with one another.  */
69c7a68eb7Smrg static const struct attribute_spec::exclusions attr_noreturn_exclusions[] =
70c7a68eb7Smrg {
71c7a68eb7Smrg   ATTR_EXCL ("noreturn", true, true, true),
72c7a68eb7Smrg   ATTR_EXCL ("alloc_align", true, true, true),
73c7a68eb7Smrg   ATTR_EXCL ("alloc_size", true, true, true),
74c7a68eb7Smrg   ATTR_EXCL ("const", true, true, true),
75c7a68eb7Smrg   ATTR_EXCL ("malloc", true, true, true),
76c7a68eb7Smrg   ATTR_EXCL ("pure", true, true, true),
77c7a68eb7Smrg   ATTR_EXCL ("returns_twice", true, true, true),
78c7a68eb7Smrg   ATTR_EXCL ("warn_unused_result", true, true, true),
79c7a68eb7Smrg   ATTR_EXCL (NULL, false, false, false),
80c7a68eb7Smrg };
81c7a68eb7Smrg 
82c7a68eb7Smrg static const struct attribute_spec::exclusions attr_returns_twice_exclusions[] =
83c7a68eb7Smrg {
84c7a68eb7Smrg   ATTR_EXCL ("noreturn", true, true, true),
85c7a68eb7Smrg   ATTR_EXCL (NULL, false, false, false),
86c7a68eb7Smrg };
87c7a68eb7Smrg 
88c7a68eb7Smrg static const struct attribute_spec::exclusions attr_const_pure_exclusions[] =
89c7a68eb7Smrg {
90c7a68eb7Smrg   ATTR_EXCL ("const", true, true, true),
91c7a68eb7Smrg   ATTR_EXCL ("noreturn", true, true, true),
92c7a68eb7Smrg   ATTR_EXCL ("pure", true, true, true),
93c7a68eb7Smrg   ATTR_EXCL (NULL, false, false, false)
94c7a68eb7Smrg };
95c7a68eb7Smrg 
9663d1a8abSmrg /* Table of machine-independent attributes supported in GIMPLE.  */
9763d1a8abSmrg const struct attribute_spec lto_attribute_table[] =
9863d1a8abSmrg {
99c7a68eb7Smrg   /* { name, min_len, max_len, decl_req, type_req, fn_type_req,
100c7a68eb7Smrg        affects_type_identity, handler, exclude } */
101c7a68eb7Smrg   { "noreturn",               0, 0, true,  false, false, false,
102c7a68eb7Smrg 			      handle_noreturn_attribute,
103c7a68eb7Smrg 			      attr_noreturn_exclusions },
104c7a68eb7Smrg   { "leaf",		      0, 0, true,  false, false, false,
105c7a68eb7Smrg 			      handle_leaf_attribute, NULL },
10663d1a8abSmrg   /* The same comments as for noreturn attributes apply to const ones.  */
107c7a68eb7Smrg   { "const",                  0, 0, true,  false, false, false,
108c7a68eb7Smrg 			      handle_const_attribute,
109c7a68eb7Smrg 			      attr_const_pure_exclusions },
110c7a68eb7Smrg   { "malloc",                 0, 0, true,  false, false, false,
111c7a68eb7Smrg 			      handle_malloc_attribute, NULL },
112c7a68eb7Smrg   { "pure",                   0, 0, true,  false, false, false,
113c7a68eb7Smrg 			      handle_pure_attribute,
114c7a68eb7Smrg 			      attr_const_pure_exclusions },
115c7a68eb7Smrg   { "no vops",                0, 0, true,  false, false, false,
116c7a68eb7Smrg 			      handle_novops_attribute, NULL },
117c7a68eb7Smrg   { "nonnull",                0, -1, false, true, true, false,
118c7a68eb7Smrg 			      handle_nonnull_attribute, NULL },
119c7a68eb7Smrg   { "nothrow",                0, 0, true,  false, false, false,
120c7a68eb7Smrg 			      handle_nothrow_attribute, NULL },
121c7a68eb7Smrg   { "patchable_function_entry", 1, 2, true, false, false, false,
122c7a68eb7Smrg 			      handle_patchable_function_entry_attribute,
123c7a68eb7Smrg 			      NULL },
124c7a68eb7Smrg   { "returns_twice",          0, 0, true,  false, false, false,
125c7a68eb7Smrg 			      handle_returns_twice_attribute,
126c7a68eb7Smrg 			      attr_returns_twice_exclusions },
127c7a68eb7Smrg   { "sentinel",               0, 1, false, true, true, false,
128c7a68eb7Smrg 			      handle_sentinel_attribute, NULL },
129c7a68eb7Smrg   { "type generic",           0, 0, false, true, true, false,
130c7a68eb7Smrg 			      handle_type_generic_attribute, NULL },
131c7a68eb7Smrg   { "fn spec",	 	      1, 1, false, true, true, false,
132c7a68eb7Smrg 			      handle_fnspec_attribute, NULL },
133c7a68eb7Smrg   { "transaction_pure",	      0, 0, false, true, true, false,
134c7a68eb7Smrg 			      handle_transaction_pure_attribute, NULL },
13563d1a8abSmrg   /* For internal use only.  The leading '*' both prevents its usage in
13663d1a8abSmrg      source code and signals that it may be overridden by machine tables.  */
137c7a68eb7Smrg   { "*tm regparm",            0, 0, false, true, true, false,
138c7a68eb7Smrg 			      ignore_attribute, NULL },
139c7a68eb7Smrg   { NULL,                     0, 0, false, false, false, false, NULL, NULL }
14063d1a8abSmrg };
14163d1a8abSmrg 
14263d1a8abSmrg /* Give the specifications for the format attributes, used by C and all
14363d1a8abSmrg    descendants.  */
14463d1a8abSmrg 
14563d1a8abSmrg const struct attribute_spec lto_format_attribute_table[] =
14663d1a8abSmrg {
147c7a68eb7Smrg   /* { name, min_len, max_len, decl_req, type_req, fn_type_req,
148c7a68eb7Smrg        affects_type_identity, handler, exclude } */
149c7a68eb7Smrg   { "format",                 3, 3, false, true,  true, false,
150c7a68eb7Smrg 			      handle_format_attribute, NULL },
151c7a68eb7Smrg   { "format_arg",             1, 1, false, true,  true, false,
152c7a68eb7Smrg 			      handle_format_arg_attribute, NULL },
153c7a68eb7Smrg   { NULL,                     0, 0, false, false, false, false, NULL, NULL }
15463d1a8abSmrg };
15563d1a8abSmrg 
15663d1a8abSmrg enum built_in_attribute
15763d1a8abSmrg {
15863d1a8abSmrg #define DEF_ATTR_NULL_TREE(ENUM) ENUM,
15963d1a8abSmrg #define DEF_ATTR_INT(ENUM, VALUE) ENUM,
16063d1a8abSmrg #define DEF_ATTR_STRING(ENUM, VALUE) ENUM,
16163d1a8abSmrg #define DEF_ATTR_IDENT(ENUM, STRING) ENUM,
16263d1a8abSmrg #define DEF_ATTR_TREE_LIST(ENUM, PURPOSE, VALUE, CHAIN) ENUM,
16363d1a8abSmrg #include "builtin-attrs.def"
16463d1a8abSmrg #undef DEF_ATTR_NULL_TREE
16563d1a8abSmrg #undef DEF_ATTR_INT
16663d1a8abSmrg #undef DEF_ATTR_STRING
16763d1a8abSmrg #undef DEF_ATTR_IDENT
16863d1a8abSmrg #undef DEF_ATTR_TREE_LIST
16963d1a8abSmrg   ATTR_LAST
17063d1a8abSmrg };
17163d1a8abSmrg 
17263d1a8abSmrg static GTY(()) tree built_in_attributes[(int) ATTR_LAST];
17363d1a8abSmrg 
17463d1a8abSmrg /* Builtin types.  */
17563d1a8abSmrg 
17663d1a8abSmrg enum lto_builtin_type
17763d1a8abSmrg {
17863d1a8abSmrg #define DEF_PRIMITIVE_TYPE(NAME, VALUE) NAME,
17963d1a8abSmrg #define DEF_FUNCTION_TYPE_0(NAME, RETURN) NAME,
18063d1a8abSmrg #define DEF_FUNCTION_TYPE_1(NAME, RETURN, ARG1) NAME,
18163d1a8abSmrg #define DEF_FUNCTION_TYPE_2(NAME, RETURN, ARG1, ARG2) NAME,
18263d1a8abSmrg #define DEF_FUNCTION_TYPE_3(NAME, RETURN, ARG1, ARG2, ARG3) NAME,
18363d1a8abSmrg #define DEF_FUNCTION_TYPE_4(NAME, RETURN, ARG1, ARG2, ARG3, ARG4) NAME,
18463d1a8abSmrg #define DEF_FUNCTION_TYPE_5(NAME, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5) NAME,
18563d1a8abSmrg #define DEF_FUNCTION_TYPE_6(NAME, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5, \
18663d1a8abSmrg 			    ARG6) NAME,
18763d1a8abSmrg #define DEF_FUNCTION_TYPE_7(NAME, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5, \
18863d1a8abSmrg 			    ARG6, ARG7) NAME,
18963d1a8abSmrg #define DEF_FUNCTION_TYPE_8(NAME, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5, \
19063d1a8abSmrg 			    ARG6, ARG7, ARG8) NAME,
19163d1a8abSmrg #define DEF_FUNCTION_TYPE_9(NAME, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5, \
19263d1a8abSmrg 			    ARG6, ARG7, ARG8, ARG9) NAME,
19363d1a8abSmrg #define DEF_FUNCTION_TYPE_10(NAME, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5, \
19463d1a8abSmrg 			     ARG6, ARG7, ARG8, ARG9, ARG10) NAME,
19563d1a8abSmrg #define DEF_FUNCTION_TYPE_11(NAME, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5, \
19663d1a8abSmrg 			     ARG6, ARG7, ARG8, ARG9, ARG10, ARG11) NAME,
19763d1a8abSmrg #define DEF_FUNCTION_TYPE_VAR_0(NAME, RETURN) NAME,
19863d1a8abSmrg #define DEF_FUNCTION_TYPE_VAR_1(NAME, RETURN, ARG1) NAME,
19963d1a8abSmrg #define DEF_FUNCTION_TYPE_VAR_2(NAME, RETURN, ARG1, ARG2) NAME,
20063d1a8abSmrg #define DEF_FUNCTION_TYPE_VAR_3(NAME, RETURN, ARG1, ARG2, ARG3) NAME,
20163d1a8abSmrg #define DEF_FUNCTION_TYPE_VAR_4(NAME, RETURN, ARG1, ARG2, ARG3, ARG4) NAME,
20263d1a8abSmrg #define DEF_FUNCTION_TYPE_VAR_5(NAME, RETURN, ARG1, ARG2, ARG3, ARG4, ARG6) \
20363d1a8abSmrg 				NAME,
20463d1a8abSmrg #define DEF_FUNCTION_TYPE_VAR_6(NAME, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5, \
20563d1a8abSmrg 				 ARG6) NAME,
20663d1a8abSmrg #define DEF_FUNCTION_TYPE_VAR_7(NAME, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5, \
20763d1a8abSmrg 				ARG6, ARG7) NAME,
20863d1a8abSmrg #define DEF_POINTER_TYPE(NAME, TYPE) NAME,
20963d1a8abSmrg #include "builtin-types.def"
21063d1a8abSmrg #undef DEF_PRIMITIVE_TYPE
21163d1a8abSmrg #undef DEF_FUNCTION_TYPE_0
21263d1a8abSmrg #undef DEF_FUNCTION_TYPE_1
21363d1a8abSmrg #undef DEF_FUNCTION_TYPE_2
21463d1a8abSmrg #undef DEF_FUNCTION_TYPE_3
21563d1a8abSmrg #undef DEF_FUNCTION_TYPE_4
21663d1a8abSmrg #undef DEF_FUNCTION_TYPE_5
21763d1a8abSmrg #undef DEF_FUNCTION_TYPE_6
21863d1a8abSmrg #undef DEF_FUNCTION_TYPE_7
21963d1a8abSmrg #undef DEF_FUNCTION_TYPE_8
22063d1a8abSmrg #undef DEF_FUNCTION_TYPE_9
22163d1a8abSmrg #undef DEF_FUNCTION_TYPE_10
22263d1a8abSmrg #undef DEF_FUNCTION_TYPE_11
22363d1a8abSmrg #undef DEF_FUNCTION_TYPE_VAR_0
22463d1a8abSmrg #undef DEF_FUNCTION_TYPE_VAR_1
22563d1a8abSmrg #undef DEF_FUNCTION_TYPE_VAR_2
22663d1a8abSmrg #undef DEF_FUNCTION_TYPE_VAR_3
22763d1a8abSmrg #undef DEF_FUNCTION_TYPE_VAR_4
22863d1a8abSmrg #undef DEF_FUNCTION_TYPE_VAR_5
22963d1a8abSmrg #undef DEF_FUNCTION_TYPE_VAR_6
23063d1a8abSmrg #undef DEF_FUNCTION_TYPE_VAR_7
23163d1a8abSmrg #undef DEF_POINTER_TYPE
23263d1a8abSmrg   BT_LAST
23363d1a8abSmrg };
23463d1a8abSmrg 
23563d1a8abSmrg typedef enum lto_builtin_type builtin_type;
23663d1a8abSmrg 
23763d1a8abSmrg static GTY(()) tree builtin_types[(int) BT_LAST + 1];
23863d1a8abSmrg 
23963d1a8abSmrg static GTY(()) tree string_type_node;
24063d1a8abSmrg static GTY(()) tree const_string_type_node;
24163d1a8abSmrg static GTY(()) tree wint_type_node;
24263d1a8abSmrg static GTY(()) tree intmax_type_node;
24363d1a8abSmrg static GTY(()) tree uintmax_type_node;
24463d1a8abSmrg static GTY(()) tree signed_size_type_node;
24563d1a8abSmrg 
24663d1a8abSmrg /* Flags needed to process builtins.def.  */
24763d1a8abSmrg int flag_isoc94;
24863d1a8abSmrg int flag_isoc99;
24963d1a8abSmrg int flag_isoc11;
250*ec02198aSmrg int flag_isoc2x;
25163d1a8abSmrg 
25263d1a8abSmrg /* Attribute handlers.  */
25363d1a8abSmrg 
25463d1a8abSmrg /* Handle a "noreturn" attribute; arguments as in
25563d1a8abSmrg    struct attribute_spec.handler.  */
25663d1a8abSmrg 
25763d1a8abSmrg static tree
handle_noreturn_attribute(tree * node,tree ARG_UNUSED (name),tree ARG_UNUSED (args),int ARG_UNUSED (flags),bool * ARG_UNUSED (no_add_attrs))25863d1a8abSmrg handle_noreturn_attribute (tree *node, tree ARG_UNUSED (name),
25963d1a8abSmrg 			   tree ARG_UNUSED (args), int ARG_UNUSED (flags),
26063d1a8abSmrg 			   bool * ARG_UNUSED (no_add_attrs))
26163d1a8abSmrg {
26263d1a8abSmrg   tree type = TREE_TYPE (*node);
26363d1a8abSmrg 
26463d1a8abSmrg   if (TREE_CODE (*node) == FUNCTION_DECL)
26563d1a8abSmrg     TREE_THIS_VOLATILE (*node) = 1;
26663d1a8abSmrg   else if (TREE_CODE (type) == POINTER_TYPE
26763d1a8abSmrg 	   && TREE_CODE (TREE_TYPE (type)) == FUNCTION_TYPE)
26863d1a8abSmrg     TREE_TYPE (*node)
26963d1a8abSmrg       = build_pointer_type
27063d1a8abSmrg 	(build_type_variant (TREE_TYPE (type),
27163d1a8abSmrg 			     TYPE_READONLY (TREE_TYPE (type)), 1));
27263d1a8abSmrg   else
27363d1a8abSmrg     gcc_unreachable ();
27463d1a8abSmrg 
27563d1a8abSmrg   return NULL_TREE;
27663d1a8abSmrg }
27763d1a8abSmrg 
27863d1a8abSmrg /* Handle a "leaf" attribute; arguments as in
27963d1a8abSmrg    struct attribute_spec.handler.  */
28063d1a8abSmrg 
28163d1a8abSmrg static tree
handle_leaf_attribute(tree * node,tree name,tree ARG_UNUSED (args),int ARG_UNUSED (flags),bool * no_add_attrs)28263d1a8abSmrg handle_leaf_attribute (tree *node, tree name,
28363d1a8abSmrg 		       tree ARG_UNUSED (args),
28463d1a8abSmrg 		       int ARG_UNUSED (flags), bool *no_add_attrs)
28563d1a8abSmrg {
28663d1a8abSmrg   if (TREE_CODE (*node) != FUNCTION_DECL)
28763d1a8abSmrg     {
28863d1a8abSmrg       warning (OPT_Wattributes, "%qE attribute ignored", name);
28963d1a8abSmrg       *no_add_attrs = true;
29063d1a8abSmrg     }
29163d1a8abSmrg   if (!TREE_PUBLIC (*node))
29263d1a8abSmrg     {
29363d1a8abSmrg       warning (OPT_Wattributes, "%qE attribute has no effect on unit local functions", name);
29463d1a8abSmrg       *no_add_attrs = true;
29563d1a8abSmrg     }
29663d1a8abSmrg 
29763d1a8abSmrg   return NULL_TREE;
29863d1a8abSmrg }
29963d1a8abSmrg 
30063d1a8abSmrg /* Handle a "const" attribute; arguments as in
30163d1a8abSmrg    struct attribute_spec.handler.  */
30263d1a8abSmrg 
30363d1a8abSmrg static tree
handle_const_attribute(tree * node,tree ARG_UNUSED (name),tree ARG_UNUSED (args),int ARG_UNUSED (flags),bool * ARG_UNUSED (no_add_attrs))30463d1a8abSmrg handle_const_attribute (tree *node, tree ARG_UNUSED (name),
30563d1a8abSmrg 			tree ARG_UNUSED (args), int ARG_UNUSED (flags),
30663d1a8abSmrg 			bool * ARG_UNUSED (no_add_attrs))
30763d1a8abSmrg {
308c7a68eb7Smrg   if (TREE_CODE (*node) != FUNCTION_DECL
3090fc04c29Smrg       || !fndecl_built_in_p (*node))
310c7a68eb7Smrg     inform (UNKNOWN_LOCATION, "%s:%s: %E: %E", __FILE__, __func__, *node, name);
311c7a68eb7Smrg 
31263d1a8abSmrg   tree type = TREE_TYPE (*node);
31363d1a8abSmrg 
31463d1a8abSmrg   /* See FIXME comment on noreturn in c_common_attribute_table.  */
31563d1a8abSmrg   if (TREE_CODE (*node) == FUNCTION_DECL)
31663d1a8abSmrg     TREE_READONLY (*node) = 1;
31763d1a8abSmrg   else if (TREE_CODE (type) == POINTER_TYPE
31863d1a8abSmrg 	   && TREE_CODE (TREE_TYPE (type)) == FUNCTION_TYPE)
31963d1a8abSmrg     TREE_TYPE (*node)
32063d1a8abSmrg       = build_pointer_type
32163d1a8abSmrg 	(build_type_variant (TREE_TYPE (type), 1,
32263d1a8abSmrg 			     TREE_THIS_VOLATILE (TREE_TYPE (type))));
32363d1a8abSmrg   else
32463d1a8abSmrg     gcc_unreachable ();
32563d1a8abSmrg 
32663d1a8abSmrg   return NULL_TREE;
32763d1a8abSmrg }
32863d1a8abSmrg 
32963d1a8abSmrg 
33063d1a8abSmrg /* Handle a "malloc" attribute; arguments as in
33163d1a8abSmrg    struct attribute_spec.handler.  */
33263d1a8abSmrg 
33363d1a8abSmrg static tree
handle_malloc_attribute(tree * node,tree ARG_UNUSED (name),tree ARG_UNUSED (args),int ARG_UNUSED (flags),bool * ARG_UNUSED (no_add_attrs))33463d1a8abSmrg handle_malloc_attribute (tree *node, tree ARG_UNUSED (name),
33563d1a8abSmrg 			 tree ARG_UNUSED (args), int ARG_UNUSED (flags),
33663d1a8abSmrg 			 bool * ARG_UNUSED (no_add_attrs))
33763d1a8abSmrg {
33863d1a8abSmrg   if (TREE_CODE (*node) == FUNCTION_DECL
33963d1a8abSmrg       && POINTER_TYPE_P (TREE_TYPE (TREE_TYPE (*node))))
34063d1a8abSmrg     DECL_IS_MALLOC (*node) = 1;
34163d1a8abSmrg   else
34263d1a8abSmrg     gcc_unreachable ();
34363d1a8abSmrg 
34463d1a8abSmrg   return NULL_TREE;
34563d1a8abSmrg }
34663d1a8abSmrg 
34763d1a8abSmrg 
34863d1a8abSmrg /* Handle a "pure" attribute; arguments as in
34963d1a8abSmrg    struct attribute_spec.handler.  */
35063d1a8abSmrg 
35163d1a8abSmrg static tree
handle_pure_attribute(tree * node,tree ARG_UNUSED (name),tree ARG_UNUSED (args),int ARG_UNUSED (flags),bool * ARG_UNUSED (no_add_attrs))35263d1a8abSmrg handle_pure_attribute (tree *node, tree ARG_UNUSED (name),
35363d1a8abSmrg 		       tree ARG_UNUSED (args), int ARG_UNUSED (flags),
35463d1a8abSmrg 		       bool * ARG_UNUSED (no_add_attrs))
35563d1a8abSmrg {
35663d1a8abSmrg   if (TREE_CODE (*node) == FUNCTION_DECL)
35763d1a8abSmrg     DECL_PURE_P (*node) = 1;
35863d1a8abSmrg   else
35963d1a8abSmrg     gcc_unreachable ();
36063d1a8abSmrg 
36163d1a8abSmrg   return NULL_TREE;
36263d1a8abSmrg }
36363d1a8abSmrg 
36463d1a8abSmrg 
36563d1a8abSmrg /* Handle a "no vops" attribute; arguments as in
36663d1a8abSmrg    struct attribute_spec.handler.  */
36763d1a8abSmrg 
36863d1a8abSmrg static tree
handle_novops_attribute(tree * node,tree ARG_UNUSED (name),tree ARG_UNUSED (args),int ARG_UNUSED (flags),bool * ARG_UNUSED (no_add_attrs))36963d1a8abSmrg handle_novops_attribute (tree *node, tree ARG_UNUSED (name),
37063d1a8abSmrg 			 tree ARG_UNUSED (args), int ARG_UNUSED (flags),
37163d1a8abSmrg 			 bool *ARG_UNUSED (no_add_attrs))
37263d1a8abSmrg {
37363d1a8abSmrg   gcc_assert (TREE_CODE (*node) == FUNCTION_DECL);
37463d1a8abSmrg   DECL_IS_NOVOPS (*node) = 1;
37563d1a8abSmrg   return NULL_TREE;
37663d1a8abSmrg }
37763d1a8abSmrg 
37863d1a8abSmrg 
37963d1a8abSmrg /* Helper for nonnull attribute handling; fetch the operand number
38063d1a8abSmrg    from the attribute argument list.  */
38163d1a8abSmrg 
38263d1a8abSmrg static bool
get_nonnull_operand(tree arg_num_expr,unsigned HOST_WIDE_INT * valp)38363d1a8abSmrg get_nonnull_operand (tree arg_num_expr, unsigned HOST_WIDE_INT *valp)
38463d1a8abSmrg {
38563d1a8abSmrg   /* Verify the arg number is a constant.  */
38663d1a8abSmrg   if (!tree_fits_uhwi_p (arg_num_expr))
38763d1a8abSmrg     return false;
38863d1a8abSmrg 
38963d1a8abSmrg   *valp = TREE_INT_CST_LOW (arg_num_expr);
39063d1a8abSmrg   return true;
39163d1a8abSmrg }
39263d1a8abSmrg 
39363d1a8abSmrg /* Handle the "nonnull" attribute.  */
39463d1a8abSmrg 
39563d1a8abSmrg static tree
handle_nonnull_attribute(tree * node,tree ARG_UNUSED (name),tree args,int ARG_UNUSED (flags),bool * ARG_UNUSED (no_add_attrs))39663d1a8abSmrg handle_nonnull_attribute (tree *node, tree ARG_UNUSED (name),
39763d1a8abSmrg 			  tree args, int ARG_UNUSED (flags),
39863d1a8abSmrg 			  bool * ARG_UNUSED (no_add_attrs))
39963d1a8abSmrg {
40063d1a8abSmrg   tree type = *node;
40163d1a8abSmrg 
40263d1a8abSmrg   /* If no arguments are specified, all pointer arguments should be
40363d1a8abSmrg      non-null.  Verify a full prototype is given so that the arguments
40463d1a8abSmrg      will have the correct types when we actually check them later.
40563d1a8abSmrg      Avoid diagnosing type-generic built-ins since those have no
40663d1a8abSmrg      prototype.  */
40763d1a8abSmrg   if (!args)
40863d1a8abSmrg     {
40963d1a8abSmrg       gcc_assert (prototype_p (type)
41063d1a8abSmrg 		  || !TYPE_ATTRIBUTES (type)
41163d1a8abSmrg 		  || lookup_attribute ("type generic", TYPE_ATTRIBUTES (type)));
41263d1a8abSmrg 
41363d1a8abSmrg       return NULL_TREE;
41463d1a8abSmrg     }
41563d1a8abSmrg 
41663d1a8abSmrg   /* Argument list specified.  Verify that each argument number references
41763d1a8abSmrg      a pointer argument.  */
41863d1a8abSmrg   for (; args; args = TREE_CHAIN (args))
41963d1a8abSmrg     {
42063d1a8abSmrg       tree argument;
42163d1a8abSmrg       unsigned HOST_WIDE_INT arg_num = 0, ck_num;
42263d1a8abSmrg 
42363d1a8abSmrg       if (!get_nonnull_operand (TREE_VALUE (args), &arg_num))
42463d1a8abSmrg 	gcc_unreachable ();
42563d1a8abSmrg 
42663d1a8abSmrg       argument = TYPE_ARG_TYPES (type);
42763d1a8abSmrg       if (argument)
42863d1a8abSmrg 	{
42963d1a8abSmrg 	  for (ck_num = 1; ; ck_num++)
43063d1a8abSmrg 	    {
43163d1a8abSmrg 	      if (!argument || ck_num == arg_num)
43263d1a8abSmrg 		break;
43363d1a8abSmrg 	      argument = TREE_CHAIN (argument);
43463d1a8abSmrg 	    }
43563d1a8abSmrg 
43663d1a8abSmrg 	  gcc_assert (argument
43763d1a8abSmrg 		      && TREE_CODE (TREE_VALUE (argument)) == POINTER_TYPE);
43863d1a8abSmrg 	}
43963d1a8abSmrg     }
44063d1a8abSmrg 
44163d1a8abSmrg   return NULL_TREE;
44263d1a8abSmrg }
44363d1a8abSmrg 
44463d1a8abSmrg 
44563d1a8abSmrg /* Handle a "nothrow" attribute; arguments as in
44663d1a8abSmrg    struct attribute_spec.handler.  */
44763d1a8abSmrg 
44863d1a8abSmrg static tree
handle_nothrow_attribute(tree * node,tree ARG_UNUSED (name),tree ARG_UNUSED (args),int ARG_UNUSED (flags),bool * ARG_UNUSED (no_add_attrs))44963d1a8abSmrg handle_nothrow_attribute (tree *node, tree ARG_UNUSED (name),
45063d1a8abSmrg 			  tree ARG_UNUSED (args), int ARG_UNUSED (flags),
45163d1a8abSmrg 			  bool * ARG_UNUSED (no_add_attrs))
45263d1a8abSmrg {
45363d1a8abSmrg   if (TREE_CODE (*node) == FUNCTION_DECL)
45463d1a8abSmrg     TREE_NOTHROW (*node) = 1;
45563d1a8abSmrg   else
45663d1a8abSmrg     gcc_unreachable ();
45763d1a8abSmrg 
45863d1a8abSmrg   return NULL_TREE;
45963d1a8abSmrg }
46063d1a8abSmrg 
46163d1a8abSmrg 
46263d1a8abSmrg /* Handle a "sentinel" attribute.  */
46363d1a8abSmrg 
46463d1a8abSmrg static tree
handle_sentinel_attribute(tree * node,tree ARG_UNUSED (name),tree args,int ARG_UNUSED (flags),bool * ARG_UNUSED (no_add_attrs))46563d1a8abSmrg handle_sentinel_attribute (tree *node, tree ARG_UNUSED (name), tree args,
46663d1a8abSmrg 			   int ARG_UNUSED (flags),
46763d1a8abSmrg 			   bool * ARG_UNUSED (no_add_attrs))
46863d1a8abSmrg {
46963d1a8abSmrg   gcc_assert (stdarg_p (*node));
47063d1a8abSmrg 
47163d1a8abSmrg   if (args)
47263d1a8abSmrg     {
47363d1a8abSmrg       tree position = TREE_VALUE (args);
47463d1a8abSmrg       gcc_assert (TREE_CODE (position) == INTEGER_CST);
47563d1a8abSmrg       if (tree_int_cst_lt (position, integer_zero_node))
47663d1a8abSmrg 	gcc_unreachable ();
47763d1a8abSmrg     }
47863d1a8abSmrg 
47963d1a8abSmrg   return NULL_TREE;
48063d1a8abSmrg }
48163d1a8abSmrg 
48263d1a8abSmrg /* Handle a "type_generic" attribute.  */
48363d1a8abSmrg 
48463d1a8abSmrg static tree
handle_type_generic_attribute(tree * node,tree ARG_UNUSED (name),tree ARG_UNUSED (args),int ARG_UNUSED (flags),bool * ARG_UNUSED (no_add_attrs))48563d1a8abSmrg handle_type_generic_attribute (tree *node, tree ARG_UNUSED (name),
48663d1a8abSmrg 			       tree ARG_UNUSED (args), int ARG_UNUSED (flags),
48763d1a8abSmrg 			       bool * ARG_UNUSED (no_add_attrs))
48863d1a8abSmrg {
48963d1a8abSmrg   /* Ensure we have a function type.  */
49063d1a8abSmrg   gcc_assert (TREE_CODE (*node) == FUNCTION_TYPE);
49163d1a8abSmrg 
49263d1a8abSmrg   /* Ensure we have a variadic function.  */
49363d1a8abSmrg   gcc_assert (!prototype_p (*node) || stdarg_p (*node));
49463d1a8abSmrg 
49563d1a8abSmrg   return NULL_TREE;
49663d1a8abSmrg }
49763d1a8abSmrg 
49863d1a8abSmrg /* Handle a "transaction_pure" attribute.  */
49963d1a8abSmrg 
50063d1a8abSmrg static tree
handle_transaction_pure_attribute(tree * node,tree ARG_UNUSED (name),tree ARG_UNUSED (args),int ARG_UNUSED (flags),bool * ARG_UNUSED (no_add_attrs))50163d1a8abSmrg handle_transaction_pure_attribute (tree *node, tree ARG_UNUSED (name),
50263d1a8abSmrg 				   tree ARG_UNUSED (args),
50363d1a8abSmrg 				   int ARG_UNUSED (flags),
50463d1a8abSmrg 				   bool * ARG_UNUSED (no_add_attrs))
50563d1a8abSmrg {
50663d1a8abSmrg   /* Ensure we have a function type.  */
50763d1a8abSmrg   gcc_assert (TREE_CODE (*node) == FUNCTION_TYPE);
50863d1a8abSmrg 
50963d1a8abSmrg   return NULL_TREE;
51063d1a8abSmrg }
51163d1a8abSmrg 
51263d1a8abSmrg /* Handle a "returns_twice" attribute.  */
51363d1a8abSmrg 
51463d1a8abSmrg static tree
handle_returns_twice_attribute(tree * node,tree ARG_UNUSED (name),tree ARG_UNUSED (args),int ARG_UNUSED (flags),bool * ARG_UNUSED (no_add_attrs))51563d1a8abSmrg handle_returns_twice_attribute (tree *node, tree ARG_UNUSED (name),
51663d1a8abSmrg 				tree ARG_UNUSED (args),
51763d1a8abSmrg 				int ARG_UNUSED (flags),
51863d1a8abSmrg 				bool * ARG_UNUSED (no_add_attrs))
51963d1a8abSmrg {
52063d1a8abSmrg   gcc_assert (TREE_CODE (*node) == FUNCTION_DECL);
52163d1a8abSmrg 
52263d1a8abSmrg   DECL_IS_RETURNS_TWICE (*node) = 1;
52363d1a8abSmrg 
52463d1a8abSmrg   return NULL_TREE;
52563d1a8abSmrg }
52663d1a8abSmrg 
527c7a68eb7Smrg static tree
handle_patchable_function_entry_attribute(tree *,tree,tree,int,bool *)528c7a68eb7Smrg handle_patchable_function_entry_attribute (tree *, tree, tree, int, bool *)
529c7a68eb7Smrg {
530c7a68eb7Smrg   /* Nothing to be done here.  */
531c7a68eb7Smrg   return NULL_TREE;
532c7a68eb7Smrg }
533c7a68eb7Smrg 
53463d1a8abSmrg /* Ignore the given attribute.  Used when this attribute may be usefully
53563d1a8abSmrg    overridden by the target, but is not used generically.  */
53663d1a8abSmrg 
53763d1a8abSmrg static tree
ignore_attribute(tree * ARG_UNUSED (node),tree ARG_UNUSED (name),tree ARG_UNUSED (args),int ARG_UNUSED (flags),bool * no_add_attrs)53863d1a8abSmrg ignore_attribute (tree * ARG_UNUSED (node), tree ARG_UNUSED (name),
53963d1a8abSmrg 		  tree ARG_UNUSED (args), int ARG_UNUSED (flags),
54063d1a8abSmrg 		  bool *no_add_attrs)
54163d1a8abSmrg {
54263d1a8abSmrg   *no_add_attrs = true;
54363d1a8abSmrg   return NULL_TREE;
54463d1a8abSmrg }
54563d1a8abSmrg 
54663d1a8abSmrg /* Handle a "format" attribute; arguments as in
54763d1a8abSmrg    struct attribute_spec.handler.  */
54863d1a8abSmrg 
54963d1a8abSmrg static tree
handle_format_attribute(tree * ARG_UNUSED (node),tree ARG_UNUSED (name),tree ARG_UNUSED (args),int ARG_UNUSED (flags),bool * no_add_attrs)55063d1a8abSmrg handle_format_attribute (tree * ARG_UNUSED (node), tree ARG_UNUSED (name),
55163d1a8abSmrg 			 tree ARG_UNUSED (args), int ARG_UNUSED (flags),
55263d1a8abSmrg 			 bool *no_add_attrs)
55363d1a8abSmrg {
55463d1a8abSmrg   *no_add_attrs = true;
55563d1a8abSmrg   return NULL_TREE;
55663d1a8abSmrg }
55763d1a8abSmrg 
55863d1a8abSmrg 
55963d1a8abSmrg /* Handle a "format_arg" attribute; arguments as in
56063d1a8abSmrg    struct attribute_spec.handler.  */
56163d1a8abSmrg 
56263d1a8abSmrg tree
handle_format_arg_attribute(tree * ARG_UNUSED (node),tree ARG_UNUSED (name),tree ARG_UNUSED (args),int ARG_UNUSED (flags),bool * no_add_attrs)56363d1a8abSmrg handle_format_arg_attribute (tree * ARG_UNUSED (node), tree ARG_UNUSED (name),
56463d1a8abSmrg 			     tree ARG_UNUSED (args), int ARG_UNUSED (flags),
56563d1a8abSmrg 			     bool *no_add_attrs)
56663d1a8abSmrg {
56763d1a8abSmrg   *no_add_attrs = true;
56863d1a8abSmrg   return NULL_TREE;
56963d1a8abSmrg }
57063d1a8abSmrg 
57163d1a8abSmrg 
57263d1a8abSmrg /* Handle a "fn spec" attribute; arguments as in
57363d1a8abSmrg    struct attribute_spec.handler.  */
57463d1a8abSmrg 
57563d1a8abSmrg static tree
handle_fnspec_attribute(tree * node ATTRIBUTE_UNUSED,tree ARG_UNUSED (name),tree args,int ARG_UNUSED (flags),bool * no_add_attrs ATTRIBUTE_UNUSED)57663d1a8abSmrg handle_fnspec_attribute (tree *node ATTRIBUTE_UNUSED, tree ARG_UNUSED (name),
57763d1a8abSmrg 			 tree args, int ARG_UNUSED (flags),
57863d1a8abSmrg 			 bool *no_add_attrs ATTRIBUTE_UNUSED)
57963d1a8abSmrg {
58063d1a8abSmrg   gcc_assert (args
58163d1a8abSmrg 	      && TREE_CODE (TREE_VALUE (args)) == STRING_CST
58263d1a8abSmrg 	      && !TREE_CHAIN (args));
58363d1a8abSmrg   return NULL_TREE;
58463d1a8abSmrg }
58563d1a8abSmrg 
58663d1a8abSmrg /* Cribbed from c-common.c.  */
58763d1a8abSmrg 
58863d1a8abSmrg static void
def_fn_type(builtin_type def,builtin_type ret,bool var,int n,...)58963d1a8abSmrg def_fn_type (builtin_type def, builtin_type ret, bool var, int n, ...)
59063d1a8abSmrg {
59163d1a8abSmrg   tree t;
59263d1a8abSmrg   tree *args = XALLOCAVEC (tree, n);
59363d1a8abSmrg   va_list list;
59463d1a8abSmrg   int i;
59563d1a8abSmrg   bool err = false;
59663d1a8abSmrg 
59763d1a8abSmrg   va_start (list, n);
59863d1a8abSmrg   for (i = 0; i < n; ++i)
59963d1a8abSmrg     {
60063d1a8abSmrg       builtin_type a = (builtin_type) va_arg (list, int);
60163d1a8abSmrg       t = builtin_types[a];
60263d1a8abSmrg       if (t == error_mark_node)
60363d1a8abSmrg 	err = true;
60463d1a8abSmrg       args[i] = t;
60563d1a8abSmrg     }
60663d1a8abSmrg   va_end (list);
60763d1a8abSmrg 
60863d1a8abSmrg   t = builtin_types[ret];
60963d1a8abSmrg   if (err)
61063d1a8abSmrg     t = error_mark_node;
61163d1a8abSmrg   if (t == error_mark_node)
61263d1a8abSmrg     ;
61363d1a8abSmrg   else if (var)
61463d1a8abSmrg     t = build_varargs_function_type_array (t, n, args);
61563d1a8abSmrg   else
61663d1a8abSmrg     t = build_function_type_array (t, n, args);
61763d1a8abSmrg 
61863d1a8abSmrg   builtin_types[def] = t;
61963d1a8abSmrg }
62063d1a8abSmrg 
62163d1a8abSmrg /* Used to help initialize the builtin-types.def table.  When a type of
62263d1a8abSmrg    the correct size doesn't exist, use error_mark_node instead of NULL.
62363d1a8abSmrg    The later results in segfaults even when a decl using the type doesn't
62463d1a8abSmrg    get invoked.  */
62563d1a8abSmrg 
62663d1a8abSmrg static tree
builtin_type_for_size(int size,bool unsignedp)62763d1a8abSmrg builtin_type_for_size (int size, bool unsignedp)
62863d1a8abSmrg {
62963d1a8abSmrg   tree type = lang_hooks.types.type_for_size (size, unsignedp);
63063d1a8abSmrg   return type ? type : error_mark_node;
63163d1a8abSmrg }
63263d1a8abSmrg 
63363d1a8abSmrg /* Support for DEF_BUILTIN.  */
63463d1a8abSmrg 
63563d1a8abSmrg static void
def_builtin_1(enum built_in_function fncode,const char * name,enum built_in_class fnclass,tree fntype,tree libtype,bool both_p,bool fallback_p,bool nonansi_p,tree fnattrs,bool implicit_p)63663d1a8abSmrg def_builtin_1 (enum built_in_function fncode, const char *name,
63763d1a8abSmrg 	       enum built_in_class fnclass, tree fntype, tree libtype,
63863d1a8abSmrg 	       bool both_p, bool fallback_p, bool nonansi_p,
63963d1a8abSmrg 	       tree fnattrs, bool implicit_p)
64063d1a8abSmrg {
64163d1a8abSmrg   tree decl;
64263d1a8abSmrg   const char *libname;
64363d1a8abSmrg 
64463d1a8abSmrg   if (fntype == error_mark_node)
64563d1a8abSmrg     return;
64663d1a8abSmrg 
64763d1a8abSmrg   libname = name + strlen ("__builtin_");
64863d1a8abSmrg   decl = add_builtin_function (name, fntype, fncode, fnclass,
64963d1a8abSmrg 			       (fallback_p ? libname : NULL),
65063d1a8abSmrg 			       fnattrs);
65163d1a8abSmrg 
65263d1a8abSmrg   if (both_p
65363d1a8abSmrg       && !flag_no_builtin
65463d1a8abSmrg       && !(nonansi_p && flag_no_nonansi_builtin))
65563d1a8abSmrg     add_builtin_function (libname, libtype, fncode, fnclass,
65663d1a8abSmrg 			  NULL, fnattrs);
65763d1a8abSmrg 
65863d1a8abSmrg   set_builtin_decl (fncode, decl, implicit_p);
65963d1a8abSmrg }
66063d1a8abSmrg 
66163d1a8abSmrg 
66263d1a8abSmrg /* Initialize the attribute table for all the supported builtins.  */
66363d1a8abSmrg 
66463d1a8abSmrg static void
lto_init_attributes(void)66563d1a8abSmrg lto_init_attributes (void)
66663d1a8abSmrg {
66763d1a8abSmrg   /* Fill in the built_in_attributes array.  */
66863d1a8abSmrg #define DEF_ATTR_NULL_TREE(ENUM)				\
66963d1a8abSmrg   built_in_attributes[(int) ENUM] = NULL_TREE;
67063d1a8abSmrg #define DEF_ATTR_INT(ENUM, VALUE)				\
67163d1a8abSmrg   built_in_attributes[(int) ENUM] = build_int_cst (NULL_TREE, VALUE);
67263d1a8abSmrg #define DEF_ATTR_STRING(ENUM, VALUE)				\
67363d1a8abSmrg   built_in_attributes[(int) ENUM] = build_string (strlen (VALUE), VALUE);
67463d1a8abSmrg #define DEF_ATTR_IDENT(ENUM, STRING)				\
67563d1a8abSmrg   built_in_attributes[(int) ENUM] = get_identifier (STRING);
67663d1a8abSmrg #define DEF_ATTR_TREE_LIST(ENUM, PURPOSE, VALUE, CHAIN)	\
67763d1a8abSmrg   built_in_attributes[(int) ENUM]			\
67863d1a8abSmrg     = tree_cons (built_in_attributes[(int) PURPOSE],	\
67963d1a8abSmrg 		 built_in_attributes[(int) VALUE],	\
68063d1a8abSmrg 		 built_in_attributes[(int) CHAIN]);
68163d1a8abSmrg #include "builtin-attrs.def"
68263d1a8abSmrg #undef DEF_ATTR_NULL_TREE
68363d1a8abSmrg #undef DEF_ATTR_INT
68463d1a8abSmrg #undef DEF_ATTR_STRING
68563d1a8abSmrg #undef DEF_ATTR_IDENT
68663d1a8abSmrg #undef DEF_ATTR_TREE_LIST
68763d1a8abSmrg }
68863d1a8abSmrg 
68963d1a8abSmrg /* Create builtin types and functions.  VA_LIST_REF_TYPE_NODE and
69063d1a8abSmrg    VA_LIST_ARG_TYPE_NODE are used in builtin-types.def.  */
69163d1a8abSmrg 
69263d1a8abSmrg static void
lto_define_builtins(tree va_list_ref_type_node ATTRIBUTE_UNUSED,tree va_list_arg_type_node ATTRIBUTE_UNUSED)69363d1a8abSmrg lto_define_builtins (tree va_list_ref_type_node ATTRIBUTE_UNUSED,
69463d1a8abSmrg 		     tree va_list_arg_type_node ATTRIBUTE_UNUSED)
69563d1a8abSmrg {
69663d1a8abSmrg #define DEF_PRIMITIVE_TYPE(ENUM, VALUE) \
69763d1a8abSmrg   builtin_types[ENUM] = VALUE;
69863d1a8abSmrg #define DEF_FUNCTION_TYPE_0(ENUM, RETURN) \
69963d1a8abSmrg   def_fn_type (ENUM, RETURN, 0, 0);
70063d1a8abSmrg #define DEF_FUNCTION_TYPE_1(ENUM, RETURN, ARG1) \
70163d1a8abSmrg   def_fn_type (ENUM, RETURN, 0, 1, ARG1);
70263d1a8abSmrg #define DEF_FUNCTION_TYPE_2(ENUM, RETURN, ARG1, ARG2) \
70363d1a8abSmrg   def_fn_type (ENUM, RETURN, 0, 2, ARG1, ARG2);
70463d1a8abSmrg #define DEF_FUNCTION_TYPE_3(ENUM, RETURN, ARG1, ARG2, ARG3) \
70563d1a8abSmrg   def_fn_type (ENUM, RETURN, 0, 3, ARG1, ARG2, ARG3);
70663d1a8abSmrg #define DEF_FUNCTION_TYPE_4(ENUM, RETURN, ARG1, ARG2, ARG3, ARG4) \
70763d1a8abSmrg   def_fn_type (ENUM, RETURN, 0, 4, ARG1, ARG2, ARG3, ARG4);
70863d1a8abSmrg #define DEF_FUNCTION_TYPE_5(ENUM, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5)	\
70963d1a8abSmrg   def_fn_type (ENUM, RETURN, 0, 5, ARG1, ARG2, ARG3, ARG4, ARG5);
71063d1a8abSmrg #define DEF_FUNCTION_TYPE_6(ENUM, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5, \
71163d1a8abSmrg 			    ARG6)					\
71263d1a8abSmrg   def_fn_type (ENUM, RETURN, 0, 6, ARG1, ARG2, ARG3, ARG4, ARG5, ARG6);
71363d1a8abSmrg #define DEF_FUNCTION_TYPE_7(ENUM, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5, \
71463d1a8abSmrg 			    ARG6, ARG7)					\
71563d1a8abSmrg   def_fn_type (ENUM, RETURN, 0, 7, ARG1, ARG2, ARG3, ARG4, ARG5, ARG6, ARG7);
71663d1a8abSmrg #define DEF_FUNCTION_TYPE_8(ENUM, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5, \
71763d1a8abSmrg 			    ARG6, ARG7, ARG8)				\
71863d1a8abSmrg   def_fn_type (ENUM, RETURN, 0, 8, ARG1, ARG2, ARG3, ARG4, ARG5, ARG6,	\
71963d1a8abSmrg 	       ARG7, ARG8);
72063d1a8abSmrg #define DEF_FUNCTION_TYPE_9(ENUM, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5, \
72163d1a8abSmrg 			    ARG6, ARG7, ARG8, ARG9)			\
72263d1a8abSmrg   def_fn_type (ENUM, RETURN, 0, 9, ARG1, ARG2, ARG3, ARG4, ARG5, ARG6,	\
72363d1a8abSmrg 	       ARG7, ARG8, ARG9);
72463d1a8abSmrg #define DEF_FUNCTION_TYPE_10(ENUM, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5, \
72563d1a8abSmrg 			     ARG6, ARG7, ARG8, ARG9, ARG10)		 \
72663d1a8abSmrg   def_fn_type (ENUM, RETURN, 0, 10, ARG1, ARG2, ARG3, ARG4, ARG5, ARG6,	 \
72763d1a8abSmrg 	       ARG7, ARG8, ARG9, ARG10);
72863d1a8abSmrg #define DEF_FUNCTION_TYPE_11(ENUM, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5, \
72963d1a8abSmrg 			     ARG6, ARG7, ARG8, ARG9, ARG10, ARG11)	 \
73063d1a8abSmrg   def_fn_type (ENUM, RETURN, 0, 11, ARG1, ARG2, ARG3, ARG4, ARG5, ARG6,	 \
73163d1a8abSmrg 	       ARG7, ARG8, ARG9, ARG10, ARG11);
73263d1a8abSmrg #define DEF_FUNCTION_TYPE_VAR_0(ENUM, RETURN) \
73363d1a8abSmrg   def_fn_type (ENUM, RETURN, 1, 0);
73463d1a8abSmrg #define DEF_FUNCTION_TYPE_VAR_1(ENUM, RETURN, ARG1) \
73563d1a8abSmrg   def_fn_type (ENUM, RETURN, 1, 1, ARG1);
73663d1a8abSmrg #define DEF_FUNCTION_TYPE_VAR_2(ENUM, RETURN, ARG1, ARG2) \
73763d1a8abSmrg   def_fn_type (ENUM, RETURN, 1, 2, ARG1, ARG2);
73863d1a8abSmrg #define DEF_FUNCTION_TYPE_VAR_3(ENUM, RETURN, ARG1, ARG2, ARG3) \
73963d1a8abSmrg   def_fn_type (ENUM, RETURN, 1, 3, ARG1, ARG2, ARG3);
74063d1a8abSmrg #define DEF_FUNCTION_TYPE_VAR_4(ENUM, RETURN, ARG1, ARG2, ARG3, ARG4) \
74163d1a8abSmrg   def_fn_type (ENUM, RETURN, 1, 4, ARG1, ARG2, ARG3, ARG4);
74263d1a8abSmrg #define DEF_FUNCTION_TYPE_VAR_5(ENUM, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5) \
74363d1a8abSmrg   def_fn_type (ENUM, RETURN, 1, 5, ARG1, ARG2, ARG3, ARG4, ARG5);
74463d1a8abSmrg #define DEF_FUNCTION_TYPE_VAR_6(ENUM, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5, \
74563d1a8abSmrg 				 ARG6)	\
74663d1a8abSmrg   def_fn_type (ENUM, RETURN, 1, 6, ARG1, ARG2, ARG3, ARG4, ARG5, ARG6);
74763d1a8abSmrg #define DEF_FUNCTION_TYPE_VAR_7(ENUM, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5, \
74863d1a8abSmrg 				ARG6, ARG7)				\
74963d1a8abSmrg   def_fn_type (ENUM, RETURN, 1, 7, ARG1, ARG2, ARG3, ARG4, ARG5, ARG6, ARG7);
75063d1a8abSmrg #define DEF_POINTER_TYPE(ENUM, TYPE) \
75163d1a8abSmrg   builtin_types[(int) ENUM] = build_pointer_type (builtin_types[(int) TYPE]);
75263d1a8abSmrg 
75363d1a8abSmrg #include "builtin-types.def"
75463d1a8abSmrg 
75563d1a8abSmrg #undef DEF_PRIMITIVE_TYPE
75663d1a8abSmrg #undef DEF_FUNCTION_TYPE_0
75763d1a8abSmrg #undef DEF_FUNCTION_TYPE_1
75863d1a8abSmrg #undef DEF_FUNCTION_TYPE_2
75963d1a8abSmrg #undef DEF_FUNCTION_TYPE_3
76063d1a8abSmrg #undef DEF_FUNCTION_TYPE_4
76163d1a8abSmrg #undef DEF_FUNCTION_TYPE_5
76263d1a8abSmrg #undef DEF_FUNCTION_TYPE_6
76363d1a8abSmrg #undef DEF_FUNCTION_TYPE_7
76463d1a8abSmrg #undef DEF_FUNCTION_TYPE_8
76563d1a8abSmrg #undef DEF_FUNCTION_TYPE_9
76663d1a8abSmrg #undef DEF_FUNCTION_TYPE_10
76763d1a8abSmrg #undef DEF_FUNCTION_TYPE_11
76863d1a8abSmrg #undef DEF_FUNCTION_TYPE_VAR_0
76963d1a8abSmrg #undef DEF_FUNCTION_TYPE_VAR_1
77063d1a8abSmrg #undef DEF_FUNCTION_TYPE_VAR_2
77163d1a8abSmrg #undef DEF_FUNCTION_TYPE_VAR_3
77263d1a8abSmrg #undef DEF_FUNCTION_TYPE_VAR_4
77363d1a8abSmrg #undef DEF_FUNCTION_TYPE_VAR_5
77463d1a8abSmrg #undef DEF_FUNCTION_TYPE_VAR_6
77563d1a8abSmrg #undef DEF_FUNCTION_TYPE_VAR_7
77663d1a8abSmrg #undef DEF_POINTER_TYPE
77763d1a8abSmrg   builtin_types[(int) BT_LAST] = NULL_TREE;
77863d1a8abSmrg 
77963d1a8abSmrg   lto_init_attributes ();
78063d1a8abSmrg 
78163d1a8abSmrg #define DEF_BUILTIN(ENUM, NAME, CLASS, TYPE, LIBTYPE, BOTH_P, FALLBACK_P,\
78263d1a8abSmrg 		    NONANSI_P, ATTRS, IMPLICIT, COND)			\
78363d1a8abSmrg     if (NAME && COND)							\
78463d1a8abSmrg       def_builtin_1 (ENUM, NAME, CLASS, builtin_types[(int) TYPE],	\
78563d1a8abSmrg 		     builtin_types[(int) LIBTYPE], BOTH_P, FALLBACK_P,	\
78663d1a8abSmrg 		     NONANSI_P, built_in_attributes[(int) ATTRS], IMPLICIT);
78763d1a8abSmrg #include "builtins.def"
78863d1a8abSmrg }
78963d1a8abSmrg 
79063d1a8abSmrg static GTY(()) tree registered_builtin_types;
79163d1a8abSmrg 
79263d1a8abSmrg /* Language hooks.  */
79363d1a8abSmrg 
79463d1a8abSmrg static bool
lto_complain_wrong_lang_p(const struct cl_option * option ATTRIBUTE_UNUSED)79563d1a8abSmrg lto_complain_wrong_lang_p (const struct cl_option *option ATTRIBUTE_UNUSED)
79663d1a8abSmrg {
79763d1a8abSmrg   /* The LTO front end inherits all the options from the first front
79863d1a8abSmrg      end that was used.  However, not all the original front end
79963d1a8abSmrg      options make sense in LTO.
80063d1a8abSmrg 
80163d1a8abSmrg      A real solution would be to filter this in collect2, but collect2
80263d1a8abSmrg      does not have access to all the option attributes to know what to
80363d1a8abSmrg      filter.  So, in lto1 we silently accept inherited flags and do
80463d1a8abSmrg      nothing about it.  */
80563d1a8abSmrg   return false;
80663d1a8abSmrg }
80763d1a8abSmrg 
80863d1a8abSmrg static void
lto_init_options_struct(struct gcc_options * opts)80963d1a8abSmrg lto_init_options_struct (struct gcc_options *opts)
81063d1a8abSmrg {
81163d1a8abSmrg   /* By default, C99-like requirements for complex multiply and divide.
81263d1a8abSmrg      ???  Until the complex method is encoded in the IL this is the only
81363d1a8abSmrg      safe choice.  This will pessimize Fortran code with LTO unless
81463d1a8abSmrg      people specify a complex method manually or use -ffast-math.  */
81563d1a8abSmrg   opts->x_flag_complex_method = 2;
81663d1a8abSmrg }
81763d1a8abSmrg 
81863d1a8abSmrg /* Handle command-line option SCODE.  If the option takes an argument, it is
81963d1a8abSmrg    stored in ARG, which is otherwise NULL.  VALUE holds either a numerical
82063d1a8abSmrg    argument or a binary value indicating whether the positive or negative form
82163d1a8abSmrg    of the option was supplied.  */
82263d1a8abSmrg 
82363d1a8abSmrg const char *resolution_file_name;
82463d1a8abSmrg static bool
lto_handle_option(size_t scode,const char * arg,HOST_WIDE_INT value ATTRIBUTE_UNUSED,int kind ATTRIBUTE_UNUSED,location_t loc ATTRIBUTE_UNUSED,const struct cl_option_handlers * handlers ATTRIBUTE_UNUSED)82563d1a8abSmrg lto_handle_option (size_t scode, const char *arg,
8260fc04c29Smrg 		   HOST_WIDE_INT value ATTRIBUTE_UNUSED,
8270fc04c29Smrg 		   int kind ATTRIBUTE_UNUSED,
82863d1a8abSmrg 		   location_t loc ATTRIBUTE_UNUSED,
82963d1a8abSmrg 		   const struct cl_option_handlers *handlers ATTRIBUTE_UNUSED)
83063d1a8abSmrg {
83163d1a8abSmrg   enum opt_code code = (enum opt_code) scode;
83263d1a8abSmrg   bool result = true;
83363d1a8abSmrg 
83463d1a8abSmrg   switch (code)
83563d1a8abSmrg     {
83663d1a8abSmrg     case OPT_fresolution_:
83763d1a8abSmrg       resolution_file_name = arg;
83863d1a8abSmrg       break;
83963d1a8abSmrg 
84063d1a8abSmrg     case OPT_Wabi:
84163d1a8abSmrg       warn_psabi = value;
84263d1a8abSmrg       break;
84363d1a8abSmrg 
84463d1a8abSmrg     case OPT_fwpa:
84563d1a8abSmrg       flag_wpa = value ? "" : NULL;
84663d1a8abSmrg       break;
84763d1a8abSmrg 
84863d1a8abSmrg     default:
84963d1a8abSmrg       break;
85063d1a8abSmrg     }
85163d1a8abSmrg 
85263d1a8abSmrg   return result;
85363d1a8abSmrg }
85463d1a8abSmrg 
85563d1a8abSmrg /* Perform post-option processing.  Does additional initialization based on
85663d1a8abSmrg    command-line options.  PFILENAME is the main input filename.  Returns false
85763d1a8abSmrg    to enable subsequent back-end initialization.  */
85863d1a8abSmrg 
85963d1a8abSmrg static bool
lto_post_options(const char ** pfilename ATTRIBUTE_UNUSED)86063d1a8abSmrg lto_post_options (const char **pfilename ATTRIBUTE_UNUSED)
86163d1a8abSmrg {
86263d1a8abSmrg   /* -fltrans and -fwpa are mutually exclusive.  Check for that here.  */
86363d1a8abSmrg   if (flag_wpa && flag_ltrans)
8640fc04c29Smrg     error ("%<-fwpa%> and %<-fltrans%> are mutually exclusive");
86563d1a8abSmrg 
86663d1a8abSmrg   if (flag_ltrans)
86763d1a8abSmrg     {
86863d1a8abSmrg       flag_generate_lto = 0;
86963d1a8abSmrg 
87063d1a8abSmrg       /* During LTRANS, we are not looking at the whole program, only
87163d1a8abSmrg 	 a subset of the whole callgraph.  */
87263d1a8abSmrg       flag_whole_program = 0;
87363d1a8abSmrg     }
87463d1a8abSmrg 
87563d1a8abSmrg   if (flag_wpa)
87663d1a8abSmrg     flag_generate_lto = 1;
87763d1a8abSmrg 
87863d1a8abSmrg   /* Initialize the codegen flags according to the output type.  */
87963d1a8abSmrg   switch (flag_lto_linker_output)
88063d1a8abSmrg     {
88163d1a8abSmrg     case LTO_LINKER_OUTPUT_REL: /* .o: incremental link producing LTO IL  */
8820fc04c29Smrg       /* Configure compiler same way as normal frontend would do with -flto:
8830fc04c29Smrg 	 this way we read the trees (declarations & types), symbol table,
8840fc04c29Smrg 	 optimization summaries and link them. Subsequently we output new LTO
8850fc04c29Smrg 	 file.  */
8860fc04c29Smrg       flag_lto = "";
8870fc04c29Smrg       flag_incremental_link = INCREMENTAL_LINK_LTO;
88863d1a8abSmrg       flag_whole_program = 0;
8890fc04c29Smrg       flag_wpa = 0;
8900fc04c29Smrg       flag_generate_lto = 1;
8910fc04c29Smrg       /* It would be cool to produce .o file directly, but our current
8920fc04c29Smrg 	 simple objects does not contain the lto symbol markers.  Go the slow
8930fc04c29Smrg 	 way through the asm file.  */
8940fc04c29Smrg       lang_hooks.lto.begin_section = lhd_begin_section;
8950fc04c29Smrg       lang_hooks.lto.append_data = lhd_append_data;
8960fc04c29Smrg       lang_hooks.lto.end_section = lhd_end_section;
8970fc04c29Smrg       if (flag_ltrans)
8980fc04c29Smrg 	error ("%<-flinker-output=rel%> and %<-fltrans%> are mutually "
8990fc04c29Smrg 	       "exclussive");
9000fc04c29Smrg       break;
9010fc04c29Smrg 
9020fc04c29Smrg     case LTO_LINKER_OUTPUT_NOLTOREL: /* .o: incremental link producing asm  */
9030fc04c29Smrg       flag_whole_program = 0;
9040fc04c29Smrg       flag_incremental_link = INCREMENTAL_LINK_NOLTO;
90563d1a8abSmrg       break;
90663d1a8abSmrg 
90763d1a8abSmrg     case LTO_LINKER_OUTPUT_DYN: /* .so: PID library */
90863d1a8abSmrg       /* On some targets, like i386 it makes sense to build PIC library wihout
90963d1a8abSmrg 	 -fpic for performance reasons.  So no need to adjust flags.  */
91063d1a8abSmrg       break;
91163d1a8abSmrg 
91263d1a8abSmrg     case LTO_LINKER_OUTPUT_PIE: /* PIE binary */
91363d1a8abSmrg       /* If -fPIC or -fPIE was used at compile time, be sure that
91463d1a8abSmrg          flag_pie is 2.  */
91563d1a8abSmrg       flag_pie = MAX (flag_pie, flag_pic);
91663d1a8abSmrg       flag_pic = flag_pie;
91763d1a8abSmrg       flag_shlib = 0;
91863d1a8abSmrg       break;
91963d1a8abSmrg 
92063d1a8abSmrg     case LTO_LINKER_OUTPUT_EXEC: /* Normal executable */
92163d1a8abSmrg       flag_pic = 0;
92263d1a8abSmrg       flag_pie = 0;
92363d1a8abSmrg       flag_shlib = 0;
92463d1a8abSmrg       break;
92563d1a8abSmrg 
92663d1a8abSmrg     case LTO_LINKER_OUTPUT_UNKNOWN:
92763d1a8abSmrg       break;
92863d1a8abSmrg     }
92963d1a8abSmrg 
93063d1a8abSmrg   /* Excess precision other than "fast" requires front-end
93163d1a8abSmrg      support.  */
932*ec02198aSmrg   if (flag_excess_precision == EXCESS_PRECISION_DEFAULT)
933*ec02198aSmrg     flag_excess_precision = EXCESS_PRECISION_FAST;
93463d1a8abSmrg 
93563d1a8abSmrg   /* When partitioning, we can tear appart STRING_CSTs uses from the same
93663d1a8abSmrg      TU into multiple partitions.  Without constant merging the constants
93763d1a8abSmrg      might not be equal at runtime.  See PR50199.  */
93863d1a8abSmrg   if (!flag_merge_constants)
93963d1a8abSmrg     flag_merge_constants = 1;
94063d1a8abSmrg 
94163d1a8abSmrg   /* Initialize the compiler back end.  */
94263d1a8abSmrg   return false;
94363d1a8abSmrg }
94463d1a8abSmrg 
94563d1a8abSmrg /* Return a data type that has machine mode MODE.
94663d1a8abSmrg    If the mode is an integer,
94763d1a8abSmrg    then UNSIGNEDP selects between signed and unsigned types.
94863d1a8abSmrg    If the mode is a fixed-point mode,
94963d1a8abSmrg    then UNSIGNEDP selects between saturating and nonsaturating types.  */
95063d1a8abSmrg 
95163d1a8abSmrg static tree
lto_type_for_mode(machine_mode mode,int unsigned_p)95263d1a8abSmrg lto_type_for_mode (machine_mode mode, int unsigned_p)
95363d1a8abSmrg {
95463d1a8abSmrg   tree t;
95563d1a8abSmrg   int i;
95663d1a8abSmrg 
95763d1a8abSmrg   if (mode == TYPE_MODE (integer_type_node))
95863d1a8abSmrg     return unsigned_p ? unsigned_type_node : integer_type_node;
95963d1a8abSmrg 
96063d1a8abSmrg   if (mode == TYPE_MODE (signed_char_type_node))
96163d1a8abSmrg     return unsigned_p ? unsigned_char_type_node : signed_char_type_node;
96263d1a8abSmrg 
96363d1a8abSmrg   if (mode == TYPE_MODE (short_integer_type_node))
96463d1a8abSmrg     return unsigned_p ? short_unsigned_type_node : short_integer_type_node;
96563d1a8abSmrg 
96663d1a8abSmrg   if (mode == TYPE_MODE (long_integer_type_node))
96763d1a8abSmrg     return unsigned_p ? long_unsigned_type_node : long_integer_type_node;
96863d1a8abSmrg 
96963d1a8abSmrg   if (mode == TYPE_MODE (long_long_integer_type_node))
97063d1a8abSmrg     return unsigned_p ? long_long_unsigned_type_node : long_long_integer_type_node;
97163d1a8abSmrg 
97263d1a8abSmrg   for (i = 0; i < NUM_INT_N_ENTS; i ++)
97363d1a8abSmrg     if (int_n_enabled_p[i]
97463d1a8abSmrg 	&& mode == int_n_data[i].m)
97563d1a8abSmrg       return (unsigned_p ? int_n_trees[i].unsigned_type
97663d1a8abSmrg 	      : int_n_trees[i].signed_type);
97763d1a8abSmrg 
97863d1a8abSmrg   if (mode == QImode)
97963d1a8abSmrg     return unsigned_p ? unsigned_intQI_type_node : intQI_type_node;
98063d1a8abSmrg 
98163d1a8abSmrg   if (mode == HImode)
98263d1a8abSmrg     return unsigned_p ? unsigned_intHI_type_node : intHI_type_node;
98363d1a8abSmrg 
98463d1a8abSmrg   if (mode == SImode)
98563d1a8abSmrg     return unsigned_p ? unsigned_intSI_type_node : intSI_type_node;
98663d1a8abSmrg 
98763d1a8abSmrg   if (mode == DImode)
98863d1a8abSmrg     return unsigned_p ? unsigned_intDI_type_node : intDI_type_node;
98963d1a8abSmrg 
99063d1a8abSmrg #if HOST_BITS_PER_WIDE_INT >= 64
99163d1a8abSmrg   if (mode == TYPE_MODE (intTI_type_node))
99263d1a8abSmrg     return unsigned_p ? unsigned_intTI_type_node : intTI_type_node;
99363d1a8abSmrg #endif
99463d1a8abSmrg 
99563d1a8abSmrg   if (mode == TYPE_MODE (float_type_node))
99663d1a8abSmrg     return float_type_node;
99763d1a8abSmrg 
99863d1a8abSmrg   if (mode == TYPE_MODE (double_type_node))
99963d1a8abSmrg     return double_type_node;
100063d1a8abSmrg 
100163d1a8abSmrg   if (mode == TYPE_MODE (long_double_type_node))
100263d1a8abSmrg     return long_double_type_node;
100363d1a8abSmrg 
100463d1a8abSmrg   if (mode == TYPE_MODE (void_type_node))
100563d1a8abSmrg     return void_type_node;
100663d1a8abSmrg 
1007c7a68eb7Smrg   if (mode == TYPE_MODE (build_pointer_type (char_type_node))
1008c7a68eb7Smrg       || mode == TYPE_MODE (build_pointer_type (integer_type_node)))
1009c7a68eb7Smrg     {
1010c7a68eb7Smrg       unsigned int precision
1011c7a68eb7Smrg 	= GET_MODE_PRECISION (as_a <scalar_int_mode> (mode));
101263d1a8abSmrg       return (unsigned_p
1013c7a68eb7Smrg 	      ? make_unsigned_type (precision)
1014c7a68eb7Smrg 	      : make_signed_type (precision));
1015c7a68eb7Smrg     }
101663d1a8abSmrg 
101763d1a8abSmrg   if (COMPLEX_MODE_P (mode))
101863d1a8abSmrg     {
101963d1a8abSmrg       machine_mode inner_mode;
102063d1a8abSmrg       tree inner_type;
102163d1a8abSmrg 
102263d1a8abSmrg       if (mode == TYPE_MODE (complex_float_type_node))
102363d1a8abSmrg 	return complex_float_type_node;
102463d1a8abSmrg       if (mode == TYPE_MODE (complex_double_type_node))
102563d1a8abSmrg 	return complex_double_type_node;
102663d1a8abSmrg       if (mode == TYPE_MODE (complex_long_double_type_node))
102763d1a8abSmrg 	return complex_long_double_type_node;
102863d1a8abSmrg 
102963d1a8abSmrg       if (mode == TYPE_MODE (complex_integer_type_node) && !unsigned_p)
103063d1a8abSmrg 	return complex_integer_type_node;
103163d1a8abSmrg 
103263d1a8abSmrg       inner_mode = GET_MODE_INNER (mode);
103363d1a8abSmrg       inner_type = lto_type_for_mode (inner_mode, unsigned_p);
103463d1a8abSmrg       if (inner_type != NULL_TREE)
103563d1a8abSmrg 	return build_complex_type (inner_type);
103663d1a8abSmrg     }
1037c7a68eb7Smrg   else if (GET_MODE_CLASS (mode) == MODE_VECTOR_BOOL
1038c7a68eb7Smrg 	   && valid_vector_subparts_p (GET_MODE_NUNITS (mode)))
1039c7a68eb7Smrg     {
1040c7a68eb7Smrg       unsigned int elem_bits = vector_element_size (GET_MODE_BITSIZE (mode),
1041c7a68eb7Smrg 						    GET_MODE_NUNITS (mode));
1042c7a68eb7Smrg       tree bool_type = build_nonstandard_boolean_type (elem_bits);
1043c7a68eb7Smrg       return build_vector_type_for_mode (bool_type, mode);
1044c7a68eb7Smrg     }
1045c7a68eb7Smrg   else if (VECTOR_MODE_P (mode)
1046c7a68eb7Smrg 	   && valid_vector_subparts_p (GET_MODE_NUNITS (mode)))
104763d1a8abSmrg     {
104863d1a8abSmrg       machine_mode inner_mode = GET_MODE_INNER (mode);
104963d1a8abSmrg       tree inner_type = lto_type_for_mode (inner_mode, unsigned_p);
105063d1a8abSmrg       if (inner_type != NULL_TREE)
105163d1a8abSmrg 	return build_vector_type_for_mode (inner_type, mode);
105263d1a8abSmrg     }
105363d1a8abSmrg 
1054*ec02198aSmrg   if (dfloat32_type_node != NULL_TREE
1055*ec02198aSmrg       && mode == TYPE_MODE (dfloat32_type_node))
105663d1a8abSmrg     return dfloat32_type_node;
1057*ec02198aSmrg   if (dfloat64_type_node != NULL_TREE
1058*ec02198aSmrg       && mode == TYPE_MODE (dfloat64_type_node))
105963d1a8abSmrg     return dfloat64_type_node;
1060*ec02198aSmrg   if (dfloat128_type_node != NULL_TREE
1061*ec02198aSmrg       && mode == TYPE_MODE (dfloat128_type_node))
106263d1a8abSmrg     return dfloat128_type_node;
106363d1a8abSmrg 
106463d1a8abSmrg   if (ALL_SCALAR_FIXED_POINT_MODE_P (mode))
106563d1a8abSmrg     {
106663d1a8abSmrg       if (mode == TYPE_MODE (short_fract_type_node))
106763d1a8abSmrg 	return unsigned_p ? sat_short_fract_type_node : short_fract_type_node;
106863d1a8abSmrg       if (mode == TYPE_MODE (fract_type_node))
106963d1a8abSmrg 	return unsigned_p ? sat_fract_type_node : fract_type_node;
107063d1a8abSmrg       if (mode == TYPE_MODE (long_fract_type_node))
107163d1a8abSmrg 	return unsigned_p ? sat_long_fract_type_node : long_fract_type_node;
107263d1a8abSmrg       if (mode == TYPE_MODE (long_long_fract_type_node))
107363d1a8abSmrg 	return unsigned_p ? sat_long_long_fract_type_node
107463d1a8abSmrg 			 : long_long_fract_type_node;
107563d1a8abSmrg 
107663d1a8abSmrg       if (mode == TYPE_MODE (unsigned_short_fract_type_node))
107763d1a8abSmrg 	return unsigned_p ? sat_unsigned_short_fract_type_node
107863d1a8abSmrg 			 : unsigned_short_fract_type_node;
107963d1a8abSmrg       if (mode == TYPE_MODE (unsigned_fract_type_node))
108063d1a8abSmrg 	return unsigned_p ? sat_unsigned_fract_type_node
108163d1a8abSmrg 			 : unsigned_fract_type_node;
108263d1a8abSmrg       if (mode == TYPE_MODE (unsigned_long_fract_type_node))
108363d1a8abSmrg 	return unsigned_p ? sat_unsigned_long_fract_type_node
108463d1a8abSmrg 			 : unsigned_long_fract_type_node;
108563d1a8abSmrg       if (mode == TYPE_MODE (unsigned_long_long_fract_type_node))
108663d1a8abSmrg 	return unsigned_p ? sat_unsigned_long_long_fract_type_node
108763d1a8abSmrg 			 : unsigned_long_long_fract_type_node;
108863d1a8abSmrg 
108963d1a8abSmrg       if (mode == TYPE_MODE (short_accum_type_node))
109063d1a8abSmrg 	return unsigned_p ? sat_short_accum_type_node : short_accum_type_node;
109163d1a8abSmrg       if (mode == TYPE_MODE (accum_type_node))
109263d1a8abSmrg 	return unsigned_p ? sat_accum_type_node : accum_type_node;
109363d1a8abSmrg       if (mode == TYPE_MODE (long_accum_type_node))
109463d1a8abSmrg 	return unsigned_p ? sat_long_accum_type_node : long_accum_type_node;
109563d1a8abSmrg       if (mode == TYPE_MODE (long_long_accum_type_node))
109663d1a8abSmrg 	return unsigned_p ? sat_long_long_accum_type_node
109763d1a8abSmrg 			 : long_long_accum_type_node;
109863d1a8abSmrg 
109963d1a8abSmrg       if (mode == TYPE_MODE (unsigned_short_accum_type_node))
110063d1a8abSmrg 	return unsigned_p ? sat_unsigned_short_accum_type_node
110163d1a8abSmrg 			 : unsigned_short_accum_type_node;
110263d1a8abSmrg       if (mode == TYPE_MODE (unsigned_accum_type_node))
110363d1a8abSmrg 	return unsigned_p ? sat_unsigned_accum_type_node
110463d1a8abSmrg 			 : unsigned_accum_type_node;
110563d1a8abSmrg       if (mode == TYPE_MODE (unsigned_long_accum_type_node))
110663d1a8abSmrg 	return unsigned_p ? sat_unsigned_long_accum_type_node
110763d1a8abSmrg 			 : unsigned_long_accum_type_node;
110863d1a8abSmrg       if (mode == TYPE_MODE (unsigned_long_long_accum_type_node))
110963d1a8abSmrg 	return unsigned_p ? sat_unsigned_long_long_accum_type_node
111063d1a8abSmrg 			 : unsigned_long_long_accum_type_node;
111163d1a8abSmrg 
111263d1a8abSmrg       if (mode == QQmode)
111363d1a8abSmrg 	return unsigned_p ? sat_qq_type_node : qq_type_node;
111463d1a8abSmrg       if (mode == HQmode)
111563d1a8abSmrg 	return unsigned_p ? sat_hq_type_node : hq_type_node;
111663d1a8abSmrg       if (mode == SQmode)
111763d1a8abSmrg 	return unsigned_p ? sat_sq_type_node : sq_type_node;
111863d1a8abSmrg       if (mode == DQmode)
111963d1a8abSmrg 	return unsigned_p ? sat_dq_type_node : dq_type_node;
112063d1a8abSmrg       if (mode == TQmode)
112163d1a8abSmrg 	return unsigned_p ? sat_tq_type_node : tq_type_node;
112263d1a8abSmrg 
112363d1a8abSmrg       if (mode == UQQmode)
112463d1a8abSmrg 	return unsigned_p ? sat_uqq_type_node : uqq_type_node;
112563d1a8abSmrg       if (mode == UHQmode)
112663d1a8abSmrg 	return unsigned_p ? sat_uhq_type_node : uhq_type_node;
112763d1a8abSmrg       if (mode == USQmode)
112863d1a8abSmrg 	return unsigned_p ? sat_usq_type_node : usq_type_node;
112963d1a8abSmrg       if (mode == UDQmode)
113063d1a8abSmrg 	return unsigned_p ? sat_udq_type_node : udq_type_node;
113163d1a8abSmrg       if (mode == UTQmode)
113263d1a8abSmrg 	return unsigned_p ? sat_utq_type_node : utq_type_node;
113363d1a8abSmrg 
113463d1a8abSmrg       if (mode == HAmode)
113563d1a8abSmrg 	return unsigned_p ? sat_ha_type_node : ha_type_node;
113663d1a8abSmrg       if (mode == SAmode)
113763d1a8abSmrg 	return unsigned_p ? sat_sa_type_node : sa_type_node;
113863d1a8abSmrg       if (mode == DAmode)
113963d1a8abSmrg 	return unsigned_p ? sat_da_type_node : da_type_node;
114063d1a8abSmrg       if (mode == TAmode)
114163d1a8abSmrg 	return unsigned_p ? sat_ta_type_node : ta_type_node;
114263d1a8abSmrg 
114363d1a8abSmrg       if (mode == UHAmode)
114463d1a8abSmrg 	return unsigned_p ? sat_uha_type_node : uha_type_node;
114563d1a8abSmrg       if (mode == USAmode)
114663d1a8abSmrg 	return unsigned_p ? sat_usa_type_node : usa_type_node;
114763d1a8abSmrg       if (mode == UDAmode)
114863d1a8abSmrg 	return unsigned_p ? sat_uda_type_node : uda_type_node;
114963d1a8abSmrg       if (mode == UTAmode)
115063d1a8abSmrg 	return unsigned_p ? sat_uta_type_node : uta_type_node;
115163d1a8abSmrg     }
115263d1a8abSmrg 
115363d1a8abSmrg   for (t = registered_builtin_types; t; t = TREE_CHAIN (t))
115463d1a8abSmrg     if (TYPE_MODE (TREE_VALUE (t)) == mode)
115563d1a8abSmrg       return TREE_VALUE (t);
115663d1a8abSmrg 
115763d1a8abSmrg   return NULL_TREE;
115863d1a8abSmrg }
115963d1a8abSmrg 
116063d1a8abSmrg /* Return true if we are in the global binding level.  */
116163d1a8abSmrg 
116263d1a8abSmrg static bool
lto_global_bindings_p(void)116363d1a8abSmrg lto_global_bindings_p (void)
116463d1a8abSmrg {
116563d1a8abSmrg   return cfun == NULL;
116663d1a8abSmrg }
116763d1a8abSmrg 
116863d1a8abSmrg static void
lto_set_decl_assembler_name(tree decl)116963d1a8abSmrg lto_set_decl_assembler_name (tree decl)
117063d1a8abSmrg {
117163d1a8abSmrg   /* This is almost the same as lhd_set_decl_assembler_name, except that
117263d1a8abSmrg      we need to uniquify file-scope names, even if they are not
117363d1a8abSmrg      TREE_PUBLIC, to avoid conflicts between individual files.  */
117463d1a8abSmrg   tree id;
117563d1a8abSmrg 
117663d1a8abSmrg   if (TREE_PUBLIC (decl))
117763d1a8abSmrg     id = targetm.mangle_decl_assembler_name (decl, DECL_NAME (decl));
117863d1a8abSmrg   else
117963d1a8abSmrg     {
118063d1a8abSmrg       const char *name = IDENTIFIER_POINTER (DECL_NAME (decl));
118163d1a8abSmrg       char *label;
1182*ec02198aSmrg       static unsigned long num;
118363d1a8abSmrg 
1184*ec02198aSmrg       ASM_FORMAT_PRIVATE_NAME (label, name, num++);
118563d1a8abSmrg       id = get_identifier (label);
118663d1a8abSmrg     }
118763d1a8abSmrg 
118863d1a8abSmrg   SET_DECL_ASSEMBLER_NAME (decl, id);
118963d1a8abSmrg }
119063d1a8abSmrg 
119163d1a8abSmrg static tree
lto_pushdecl(tree t ATTRIBUTE_UNUSED)119263d1a8abSmrg lto_pushdecl (tree t ATTRIBUTE_UNUSED)
119363d1a8abSmrg {
119463d1a8abSmrg   /* Do nothing, since we get all information from DWARF and LTO
119563d1a8abSmrg      sections.  */
119663d1a8abSmrg   return NULL_TREE;
119763d1a8abSmrg }
119863d1a8abSmrg 
119963d1a8abSmrg static tree
lto_getdecls(void)120063d1a8abSmrg lto_getdecls (void)
120163d1a8abSmrg {
120263d1a8abSmrg   /* We have our own write_globals langhook, hence the getdecls
120363d1a8abSmrg      langhook shouldn't be used, except by dbxout.c, so we can't
120463d1a8abSmrg      just abort here.  */
120563d1a8abSmrg   return NULL_TREE;
120663d1a8abSmrg }
120763d1a8abSmrg 
120863d1a8abSmrg static tree
lto_builtin_function(tree decl)120963d1a8abSmrg lto_builtin_function (tree decl)
121063d1a8abSmrg {
121163d1a8abSmrg   return decl;
121263d1a8abSmrg }
121363d1a8abSmrg 
121463d1a8abSmrg static void
lto_register_builtin_type(tree type,const char * name)121563d1a8abSmrg lto_register_builtin_type (tree type, const char *name)
121663d1a8abSmrg {
121763d1a8abSmrg   tree decl;
121863d1a8abSmrg 
121963d1a8abSmrg   if (!TYPE_NAME (type))
122063d1a8abSmrg     {
122163d1a8abSmrg       decl = build_decl (UNKNOWN_LOCATION, TYPE_DECL,
122263d1a8abSmrg 			 get_identifier (name), type);
122363d1a8abSmrg       DECL_ARTIFICIAL (decl) = 1;
122463d1a8abSmrg       TYPE_NAME (type) = decl;
122563d1a8abSmrg     }
122663d1a8abSmrg 
122763d1a8abSmrg   registered_builtin_types = tree_cons (0, type, registered_builtin_types);
122863d1a8abSmrg }
122963d1a8abSmrg 
123063d1a8abSmrg /* Build nodes that would have be created by the C front-end; necessary
123163d1a8abSmrg    for including builtin-types.def and ultimately builtins.def.  */
123263d1a8abSmrg 
123363d1a8abSmrg static void
lto_build_c_type_nodes(void)123463d1a8abSmrg lto_build_c_type_nodes (void)
123563d1a8abSmrg {
123663d1a8abSmrg   gcc_assert (void_type_node);
123763d1a8abSmrg 
123863d1a8abSmrg   void_list_node = build_tree_list (NULL_TREE, void_type_node);
123963d1a8abSmrg   string_type_node = build_pointer_type (char_type_node);
124063d1a8abSmrg   const_string_type_node
124163d1a8abSmrg     = build_pointer_type (build_qualified_type (char_type_node, TYPE_QUAL_CONST));
124263d1a8abSmrg 
124363d1a8abSmrg   if (strcmp (SIZE_TYPE, "unsigned int") == 0)
124463d1a8abSmrg     {
124563d1a8abSmrg       intmax_type_node = integer_type_node;
124663d1a8abSmrg       uintmax_type_node = unsigned_type_node;
124763d1a8abSmrg       signed_size_type_node = integer_type_node;
124863d1a8abSmrg     }
124963d1a8abSmrg   else if (strcmp (SIZE_TYPE, "long unsigned int") == 0)
125063d1a8abSmrg     {
125163d1a8abSmrg       intmax_type_node = long_integer_type_node;
125263d1a8abSmrg       uintmax_type_node = long_unsigned_type_node;
125363d1a8abSmrg       signed_size_type_node = long_integer_type_node;
125463d1a8abSmrg     }
125563d1a8abSmrg   else if (strcmp (SIZE_TYPE, "long long unsigned int") == 0)
125663d1a8abSmrg     {
125763d1a8abSmrg       intmax_type_node = long_long_integer_type_node;
125863d1a8abSmrg       uintmax_type_node = long_long_unsigned_type_node;
125963d1a8abSmrg       signed_size_type_node = long_long_integer_type_node;
126063d1a8abSmrg     }
126163d1a8abSmrg   else
126263d1a8abSmrg     {
126363d1a8abSmrg       int i;
126463d1a8abSmrg 
126563d1a8abSmrg       signed_size_type_node = NULL_TREE;
126663d1a8abSmrg       for (i = 0; i < NUM_INT_N_ENTS; i++)
126763d1a8abSmrg 	if (int_n_enabled_p[i])
126863d1a8abSmrg 	  {
1269*ec02198aSmrg 	    char name[50], altname[50];
127063d1a8abSmrg 	    sprintf (name, "__int%d unsigned", int_n_data[i].bitsize);
1271*ec02198aSmrg 	    sprintf (altname, "__int%d__ unsigned", int_n_data[i].bitsize);
127263d1a8abSmrg 
1273*ec02198aSmrg 	    if (strcmp (name, SIZE_TYPE) == 0
1274*ec02198aSmrg 		|| strcmp (altname, SIZE_TYPE) == 0)
127563d1a8abSmrg 	      {
127663d1a8abSmrg 		intmax_type_node = int_n_trees[i].signed_type;
127763d1a8abSmrg 		uintmax_type_node = int_n_trees[i].unsigned_type;
127863d1a8abSmrg 		signed_size_type_node = int_n_trees[i].signed_type;
127963d1a8abSmrg 	      }
128063d1a8abSmrg 	  }
128163d1a8abSmrg       if (signed_size_type_node == NULL_TREE)
128263d1a8abSmrg 	gcc_unreachable ();
128363d1a8abSmrg     }
128463d1a8abSmrg 
128563d1a8abSmrg   wint_type_node = unsigned_type_node;
128663d1a8abSmrg   pid_type_node = integer_type_node;
128763d1a8abSmrg }
128863d1a8abSmrg 
128963d1a8abSmrg /* Perform LTO-specific initialization.  */
129063d1a8abSmrg 
129163d1a8abSmrg static bool
lto_init(void)129263d1a8abSmrg lto_init (void)
129363d1a8abSmrg {
129463d1a8abSmrg   int i;
129563d1a8abSmrg 
1296c7a68eb7Smrg   /* Initialize LTO-specific data structures.  */
1297c7a68eb7Smrg   in_lto_p = true;
1298c7a68eb7Smrg 
129963d1a8abSmrg   /* We need to generate LTO if running in WPA mode.  */
13000fc04c29Smrg   flag_generate_lto = (flag_incremental_link == INCREMENTAL_LINK_LTO
13010fc04c29Smrg 		       || flag_wpa != NULL);
130263d1a8abSmrg 
130363d1a8abSmrg   /* Create the basic integer types.  */
130463d1a8abSmrg   build_common_tree_nodes (flag_signed_char);
130563d1a8abSmrg 
130663d1a8abSmrg   /* The global tree for the main identifier is filled in by
130763d1a8abSmrg      language-specific front-end initialization that is not run in the
130863d1a8abSmrg      LTO back-end.  It appears that all languages that perform such
130963d1a8abSmrg      initialization currently do so in the same way, so we do it here.  */
131063d1a8abSmrg   if (main_identifier_node == NULL_TREE)
131163d1a8abSmrg     main_identifier_node = get_identifier ("main");
131263d1a8abSmrg 
131363d1a8abSmrg   /* In the C++ front-end, fileptr_type_node is defined as a variant
131463d1a8abSmrg      copy of ptr_type_node, rather than ptr_node itself.  The
131563d1a8abSmrg      distinction should only be relevant to the front-end, so we
1316c7a68eb7Smrg      always use the C definition here in lto1.
1317c7a68eb7Smrg      Likewise for const struct tm*.  */
1318c7a68eb7Smrg   for (unsigned i = 0;
1319c7a68eb7Smrg        i < sizeof (builtin_structptr_types) / sizeof (builtin_structptr_type);
1320c7a68eb7Smrg        ++i)
1321c7a68eb7Smrg     {
1322c7a68eb7Smrg       gcc_assert (builtin_structptr_types[i].node
1323c7a68eb7Smrg 		  == builtin_structptr_types[i].base);
1324c7a68eb7Smrg       gcc_assert (TYPE_MAIN_VARIANT (builtin_structptr_types[i].node)
1325c7a68eb7Smrg 		  == builtin_structptr_types[i].base);
1326c7a68eb7Smrg     }
132763d1a8abSmrg 
132863d1a8abSmrg   lto_build_c_type_nodes ();
132963d1a8abSmrg   gcc_assert (va_list_type_node);
133063d1a8abSmrg 
133163d1a8abSmrg   if (TREE_CODE (va_list_type_node) == ARRAY_TYPE)
133263d1a8abSmrg     {
133363d1a8abSmrg       tree x = build_pointer_type (TREE_TYPE (va_list_type_node));
133463d1a8abSmrg       lto_define_builtins (x, x);
133563d1a8abSmrg     }
133663d1a8abSmrg   else
133763d1a8abSmrg     {
133863d1a8abSmrg       lto_define_builtins (build_reference_type (va_list_type_node),
133963d1a8abSmrg 			   va_list_type_node);
134063d1a8abSmrg     }
134163d1a8abSmrg 
134263d1a8abSmrg   targetm.init_builtins ();
134363d1a8abSmrg   build_common_builtin_nodes ();
134463d1a8abSmrg 
134563d1a8abSmrg   /* Assign names to the builtin types, otherwise they'll end up
134663d1a8abSmrg      as __unknown__ in debug info.
134763d1a8abSmrg      ???  We simply need to stop pre-seeding the streamer cache.
134863d1a8abSmrg      Below is modeled after from c-common.c:c_common_nodes_and_builtins  */
134963d1a8abSmrg #define NAME_TYPE(t,n) \
135063d1a8abSmrg   if (t) \
135163d1a8abSmrg     TYPE_NAME (t) = build_decl (UNKNOWN_LOCATION, TYPE_DECL, \
135263d1a8abSmrg 			        get_identifier (n), t)
135363d1a8abSmrg   NAME_TYPE (integer_type_node, "int");
135463d1a8abSmrg   NAME_TYPE (char_type_node, "char");
135563d1a8abSmrg   NAME_TYPE (long_integer_type_node, "long int");
135663d1a8abSmrg   NAME_TYPE (unsigned_type_node, "unsigned int");
135763d1a8abSmrg   NAME_TYPE (long_unsigned_type_node, "long unsigned int");
135863d1a8abSmrg   NAME_TYPE (long_long_integer_type_node, "long long int");
135963d1a8abSmrg   NAME_TYPE (long_long_unsigned_type_node, "long long unsigned int");
136063d1a8abSmrg   NAME_TYPE (short_integer_type_node, "short int");
136163d1a8abSmrg   NAME_TYPE (short_unsigned_type_node, "short unsigned int");
136263d1a8abSmrg   if (signed_char_type_node != char_type_node)
136363d1a8abSmrg     NAME_TYPE (signed_char_type_node, "signed char");
136463d1a8abSmrg   if (unsigned_char_type_node != char_type_node)
136563d1a8abSmrg     NAME_TYPE (unsigned_char_type_node, "unsigned char");
136663d1a8abSmrg   NAME_TYPE (float_type_node, "float");
136763d1a8abSmrg   NAME_TYPE (double_type_node, "double");
136863d1a8abSmrg   NAME_TYPE (long_double_type_node, "long double");
136963d1a8abSmrg   NAME_TYPE (void_type_node, "void");
137063d1a8abSmrg   NAME_TYPE (boolean_type_node, "bool");
137163d1a8abSmrg   NAME_TYPE (complex_float_type_node, "complex float");
137263d1a8abSmrg   NAME_TYPE (complex_double_type_node, "complex double");
137363d1a8abSmrg   NAME_TYPE (complex_long_double_type_node, "complex long double");
137463d1a8abSmrg   for (i = 0; i < NUM_INT_N_ENTS; i++)
137563d1a8abSmrg     if (int_n_enabled_p[i])
137663d1a8abSmrg       {
137763d1a8abSmrg 	char name[50];
137863d1a8abSmrg 	sprintf (name, "__int%d", int_n_data[i].bitsize);
137963d1a8abSmrg 	NAME_TYPE (int_n_trees[i].signed_type, name);
138063d1a8abSmrg       }
138163d1a8abSmrg #undef NAME_TYPE
138263d1a8abSmrg 
138363d1a8abSmrg   return true;
138463d1a8abSmrg }
138563d1a8abSmrg 
13860fc04c29Smrg /* Register c++-specific dumps.  */
13870fc04c29Smrg 
13880fc04c29Smrg void
lto_register_dumps(gcc::dump_manager * dumps)13890fc04c29Smrg lto_register_dumps (gcc::dump_manager *dumps)
13900fc04c29Smrg {
13910fc04c29Smrg   lto_link_dump_id = dumps->dump_register
13920fc04c29Smrg     (".lto-link", "ipa-lto-link", "ipa-lto-link",
13930fc04c29Smrg      DK_ipa, OPTGROUP_NONE, false);
13940fc04c29Smrg   decl_merge_dump_id = dumps->dump_register
13950fc04c29Smrg     (".lto-decl-merge", "ipa-lto-decl-merge", "ipa-lto-decl-merge",
13960fc04c29Smrg      DK_ipa, OPTGROUP_NONE, false);
13970fc04c29Smrg   partition_dump_id = dumps->dump_register
13980fc04c29Smrg     (".lto-partition", "ipa-lto-partition", "ipa-lto-partition",
13990fc04c29Smrg      DK_ipa, OPTGROUP_NONE, false);
14000fc04c29Smrg }
14010fc04c29Smrg 
14020fc04c29Smrg 
140363d1a8abSmrg /* Initialize tree structures required by the LTO front end.  */
140463d1a8abSmrg 
lto_init_ts(void)140563d1a8abSmrg static void lto_init_ts (void)
140663d1a8abSmrg {
140763d1a8abSmrg   tree_contains_struct[NAMESPACE_DECL][TS_DECL_MINIMAL] = 1;
140863d1a8abSmrg }
140963d1a8abSmrg 
141063d1a8abSmrg #undef LANG_HOOKS_NAME
141163d1a8abSmrg #define LANG_HOOKS_NAME "GNU GIMPLE"
141263d1a8abSmrg #undef LANG_HOOKS_OPTION_LANG_MASK
141363d1a8abSmrg #define LANG_HOOKS_OPTION_LANG_MASK lto_option_lang_mask
141463d1a8abSmrg #undef LANG_HOOKS_COMPLAIN_WRONG_LANG_P
141563d1a8abSmrg #define LANG_HOOKS_COMPLAIN_WRONG_LANG_P lto_complain_wrong_lang_p
141663d1a8abSmrg #undef LANG_HOOKS_INIT_OPTIONS_STRUCT
141763d1a8abSmrg #define LANG_HOOKS_INIT_OPTIONS_STRUCT lto_init_options_struct
14180fc04c29Smrg #undef LANG_HOOKS_REGISTER_DUMPS
14190fc04c29Smrg #define LANG_HOOKS_REGISTER_DUMPS lto_register_dumps
142063d1a8abSmrg #undef LANG_HOOKS_HANDLE_OPTION
142163d1a8abSmrg #define LANG_HOOKS_HANDLE_OPTION lto_handle_option
142263d1a8abSmrg #undef LANG_HOOKS_POST_OPTIONS
142363d1a8abSmrg #define LANG_HOOKS_POST_OPTIONS lto_post_options
142463d1a8abSmrg #undef LANG_HOOKS_GET_ALIAS_SET
142563d1a8abSmrg #define LANG_HOOKS_GET_ALIAS_SET gimple_get_alias_set
142663d1a8abSmrg #undef LANG_HOOKS_TYPE_FOR_MODE
142763d1a8abSmrg #define LANG_HOOKS_TYPE_FOR_MODE lto_type_for_mode
142863d1a8abSmrg #undef LANG_HOOKS_SET_DECL_ASSEMBLER_NAME
142963d1a8abSmrg #define LANG_HOOKS_SET_DECL_ASSEMBLER_NAME lto_set_decl_assembler_name
143063d1a8abSmrg #undef LANG_HOOKS_GLOBAL_BINDINGS_P
143163d1a8abSmrg #define LANG_HOOKS_GLOBAL_BINDINGS_P lto_global_bindings_p
143263d1a8abSmrg #undef LANG_HOOKS_PUSHDECL
143363d1a8abSmrg #define LANG_HOOKS_PUSHDECL lto_pushdecl
143463d1a8abSmrg #undef LANG_HOOKS_GETDECLS
143563d1a8abSmrg #define LANG_HOOKS_GETDECLS lto_getdecls
143663d1a8abSmrg #undef LANG_HOOKS_REGISTER_BUILTIN_TYPE
143763d1a8abSmrg #define LANG_HOOKS_REGISTER_BUILTIN_TYPE lto_register_builtin_type
143863d1a8abSmrg #undef LANG_HOOKS_BUILTIN_FUNCTION
143963d1a8abSmrg #define LANG_HOOKS_BUILTIN_FUNCTION lto_builtin_function
144063d1a8abSmrg #undef LANG_HOOKS_INIT
144163d1a8abSmrg #define LANG_HOOKS_INIT lto_init
144263d1a8abSmrg #undef LANG_HOOKS_PARSE_FILE
144363d1a8abSmrg #define LANG_HOOKS_PARSE_FILE lto_main
144463d1a8abSmrg #undef LANG_HOOKS_REDUCE_BIT_FIELD_OPERATIONS
144563d1a8abSmrg #define LANG_HOOKS_REDUCE_BIT_FIELD_OPERATIONS true
144663d1a8abSmrg #undef LANG_HOOKS_TYPES_COMPATIBLE_P
144763d1a8abSmrg #define LANG_HOOKS_TYPES_COMPATIBLE_P NULL
144863d1a8abSmrg #undef LANG_HOOKS_EH_PERSONALITY
144963d1a8abSmrg #define LANG_HOOKS_EH_PERSONALITY lto_eh_personality
145063d1a8abSmrg 
145163d1a8abSmrg /* Attribute hooks.  */
145263d1a8abSmrg #undef LANG_HOOKS_COMMON_ATTRIBUTE_TABLE
145363d1a8abSmrg #define LANG_HOOKS_COMMON_ATTRIBUTE_TABLE lto_attribute_table
145463d1a8abSmrg #undef LANG_HOOKS_FORMAT_ATTRIBUTE_TABLE
145563d1a8abSmrg #define LANG_HOOKS_FORMAT_ATTRIBUTE_TABLE lto_format_attribute_table
145663d1a8abSmrg 
145763d1a8abSmrg #undef LANG_HOOKS_BEGIN_SECTION
145863d1a8abSmrg #define LANG_HOOKS_BEGIN_SECTION lto_obj_begin_section
145963d1a8abSmrg #undef LANG_HOOKS_APPEND_DATA
146063d1a8abSmrg #define LANG_HOOKS_APPEND_DATA lto_obj_append_data
146163d1a8abSmrg #undef LANG_HOOKS_END_SECTION
146263d1a8abSmrg #define LANG_HOOKS_END_SECTION lto_obj_end_section
146363d1a8abSmrg 
146463d1a8abSmrg #undef LANG_HOOKS_INIT_TS
146563d1a8abSmrg #define LANG_HOOKS_INIT_TS lto_init_ts
146663d1a8abSmrg 
146763d1a8abSmrg struct lang_hooks lang_hooks = LANG_HOOKS_INITIALIZER;
146863d1a8abSmrg 
146963d1a8abSmrg /* Language hooks that are not part of lang_hooks.  */
147063d1a8abSmrg 
147163d1a8abSmrg tree
convert(tree type ATTRIBUTE_UNUSED,tree expr ATTRIBUTE_UNUSED)147263d1a8abSmrg convert (tree type ATTRIBUTE_UNUSED, tree expr ATTRIBUTE_UNUSED)
147363d1a8abSmrg {
147463d1a8abSmrg   gcc_unreachable ();
147563d1a8abSmrg }
147663d1a8abSmrg 
147763d1a8abSmrg /* Tree walking support.  */
147863d1a8abSmrg 
147963d1a8abSmrg static enum lto_tree_node_structure_enum
lto_tree_node_structure(union lang_tree_node * t ATTRIBUTE_UNUSED)148063d1a8abSmrg lto_tree_node_structure (union lang_tree_node *t ATTRIBUTE_UNUSED)
148163d1a8abSmrg {
148263d1a8abSmrg   return TS_LTO_GENERIC;
148363d1a8abSmrg }
148463d1a8abSmrg 
148563d1a8abSmrg #include "gtype-lto.h"
148663d1a8abSmrg #include "gt-lto-lto-lang.h"
1487