1 /* m2decl.cc provides an interface to GCC decl trees.
3 Copyright (C) 2012-2024 Free Software Foundation, Inc.
4 Contributed by Gaius Mulley <gaius@glam.ac.uk>.
6 This file is part of GNU Modula-2.
8 GNU Modula-2 is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 3, or (at your option)
13 GNU Modula-2 is distributed in the hope that it will be useful, but
14 WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with GNU Modula-2; see the file COPYING3. If not see
20 <http://www.gnu.org/licenses/>. */
22 #include "gcc-consolidation.h"
24 #include "../gm2-lang.h"
25 #include "../m2-tree.h"
33 #include "m2treelib.h"
35 #include "m2convert.h"
37 extern GTY (()) tree current_function_decl
;
39 /* Used in BuildStartFunctionType. */
40 static GTY (()) tree param_type_list
;
41 static GTY (()) tree param_list
= NULL_TREE
; /* Ready for the next time we
42 call/define a function. */
45 m2decl_DeclareM2linkStaticInitialization (location_t location
,
48 m2block_pushGlobalScope ();
49 /* Generate: int M2LINK_StaticInitialization = ScaffoldStatic; */
50 tree init
= m2decl_BuildIntegerConstant (ScaffoldStatic
);
51 tree static_init
= m2decl_DeclareKnownVariable (location
, "m2pim_M2LINK_StaticInitialization",
53 TRUE
, FALSE
, FALSE
, TRUE
, NULL_TREE
, init
);
54 m2block_popGlobalScope ();
60 m2decl_DeclareM2linkForcedModuleInitOrder (location_t location
,
61 const char *RuntimeOverride
)
63 m2block_pushGlobalScope ();
64 /* Generate: const char *ForcedModuleInitOrder = RuntimeOverride; */
65 tree ptr_to_char
= build_pointer_type (char_type_node
);
66 TYPE_READONLY (ptr_to_char
) = TRUE
;
67 tree init
= m2decl_BuildPtrToTypeString (location
, RuntimeOverride
, ptr_to_char
);
68 tree forced_order
= m2decl_DeclareKnownVariable (location
, "m2pim_M2LINK_ForcedModuleInitOrder",
70 TRUE
, FALSE
, FALSE
, TRUE
, NULL_TREE
, init
);
71 m2block_popGlobalScope ();
77 /* DeclareKnownVariable declares a variable to GCC. */
80 m2decl_DeclareKnownVariable (location_t location
, const char *name
, tree type
,
81 bool exported
, bool imported
, bool istemporary
,
82 bool isglobal
, tree scope
, tree initial
)
87 m2assert_AssertLocation (location
);
88 ASSERT (m2tree_is_type (type
), type
);
89 ASSERT_BOOL (isglobal
);
91 id
= get_identifier (name
);
92 type
= m2tree_skip_type_decl (type
);
93 decl
= build_decl (location
, VAR_DECL
, id
, type
);
95 DECL_SOURCE_LOCATION (decl
) = location
;
97 DECL_EXTERNAL (decl
) = imported
;
98 TREE_STATIC (decl
) = isglobal
;
99 TREE_PUBLIC (decl
) = exported
|| imported
;
101 gcc_assert ((istemporary
== 0) || (istemporary
== 1));
103 /* The variable was not declared by GCC, but by the front end. */
104 DECL_ARTIFICIAL (decl
) = istemporary
;
105 /* If istemporary then we don't want debug info for it. */
106 DECL_IGNORED_P (decl
) = istemporary
;
107 /* If istemporary we don't want even the fancy names of those printed in
108 -fdump-final-insns= dumps. */
109 DECL_NAMELESS (decl
) = istemporary
;
111 /* Make the variable writable. */
112 TREE_READONLY (decl
) = 0;
114 DECL_CONTEXT (decl
) = scope
;
117 DECL_INITIAL (decl
) = initial
;
119 m2block_pushDecl (decl
);
121 if (DECL_SIZE (decl
) == 0)
122 error ("storage size of %qD has not been resolved", decl
);
124 if ((TREE_PUBLIC (decl
) == 0) && DECL_EXTERNAL (decl
))
125 internal_error ("inconsistent because %qs",
126 "PUBLIC_DECL(decl) == 0 && DECL_EXTERNAL(decl) == 1");
128 m2block_addDeclExpr (build_stmt (location
, DECL_EXPR
, decl
));
133 /* DeclareKnownConstant - given a constant, value, of, type, create a
134 constant in the GCC symbol table. Note that the name of the
135 constant is not used as _all_ constants are declared in the global
136 scope. The front end deals with scoping rules - here we declare
137 all constants with no names in the global scope. This allows
138 M2SubExp and constant folding routines the liberty of operating
139 with quadruples which all assume constants can always be
143 m2decl_DeclareKnownConstant (location_t location
, tree type
, tree value
)
145 tree id
= make_node (IDENTIFIER_NODE
); /* Ignore the name of the constant. */
148 m2assert_AssertLocation (location
);
149 m2expr_ConstantExpressionWarning (value
);
150 type
= m2tree_skip_type_decl (type
);
153 decl
= build_decl (location
, CONST_DECL
, id
, type
);
155 value
= copy_node (value
);
156 TREE_TYPE (value
) = type
;
157 DECL_INITIAL (decl
) = value
;
158 TREE_TYPE (decl
) = type
;
159 decl
= m2block_global_constant (decl
);
163 /* BuildParameterDeclaration - creates and returns one parameter
164 from, name, and, type. It appends this parameter to the internal
168 m2decl_BuildParameterDeclaration (location_t location
, char *name
, tree type
,
173 m2assert_AssertLocation (location
);
174 ASSERT_BOOL (isreference
);
175 type
= m2tree_skip_type_decl (type
);
178 type
= build_reference_type (type
);
181 parm_decl
= build_decl (location
, PARM_DECL
, NULL
, type
);
183 parm_decl
= build_decl (location
, PARM_DECL
, get_identifier (name
), type
);
184 DECL_ARG_TYPE (parm_decl
) = type
;
186 TREE_READONLY (parm_decl
) = TRUE
;
188 param_list
= chainon (parm_decl
, param_list
);
190 param_type_list
= tree_cons (NULL_TREE
, type
, param_type_list
);
194 /* BuildStartFunctionDeclaration - initializes global variables ready
195 for building a function. */
198 m2decl_BuildStartFunctionDeclaration (bool uses_varargs
)
201 param_type_list
= NULL_TREE
;
203 param_type_list
= tree_cons (NULL_TREE
, void_type_node
, NULL_TREE
);
204 param_list
= NULL_TREE
; /* Ready for when we define a function. */
207 /* BuildEndFunctionDeclaration - build a function which will return a
208 value of returntype. The arguments have been created by
209 BuildParameterDeclaration. */
212 m2decl_BuildEndFunctionDeclaration (location_t location_begin
,
213 location_t location_end
, const char *name
,
214 tree returntype
, bool isexternal
,
215 bool isnested
, bool ispublic
, bool isnoreturn
)
220 m2assert_AssertLocation (location_begin
);
221 m2assert_AssertLocation (location_end
);
222 ASSERT_BOOL (isexternal
);
223 ASSERT_BOOL (isnested
);
224 ASSERT_BOOL (ispublic
);
225 returntype
= m2tree_skip_type_decl (returntype
);
226 /* The function type depends on the return type and type of args,
227 both of which we have created in BuildParameterDeclaration */
228 if (returntype
== NULL_TREE
)
229 returntype
= void_type_node
;
230 else if (TREE_CODE (returntype
) == FUNCTION_TYPE
)
231 returntype
= ptr_type_node
;
233 fntype
= build_function_type (returntype
, param_type_list
);
234 fndecl
= build_decl (location_begin
, FUNCTION_DECL
, get_identifier (name
),
238 ASSERT_CONDITION (ispublic
);
240 DECL_EXTERNAL (fndecl
) = isexternal
;
241 TREE_PUBLIC (fndecl
) = ispublic
;
242 TREE_STATIC (fndecl
) = (!isexternal
);
243 DECL_ARGUMENTS (fndecl
) = param_list
;
245 = build_decl (location_end
, RESULT_DECL
, NULL_TREE
, returntype
);
246 DECL_CONTEXT (DECL_RESULT (fndecl
)) = fndecl
;
247 TREE_TYPE (fndecl
) = fntype
;
248 TREE_THIS_VOLATILE (fndecl
) = isnoreturn
;
250 DECL_SOURCE_LOCATION (fndecl
) = location_begin
;
252 /* Prevent the optimizer from removing it if it is public. */
253 if (TREE_PUBLIC (fndecl
))
254 gm2_mark_addressable (fndecl
);
256 m2block_pushDecl (fndecl
);
258 rest_of_decl_compilation (fndecl
, 1, 0);
260 = NULL_TREE
; /* Ready for the next time we call/define a function. */
264 /* BuildModuleCtor creates the per module constructor used as part of
265 the dynamic linking scaffold. */
268 m2decl_BuildModuleCtor (tree module_ctor
)
270 decl_init_priority_insert (module_ctor
, DEFAULT_INIT_PRIORITY
);
273 /* DeclareModuleCtor configures the function to be used as a ctor. */
276 m2decl_DeclareModuleCtor (tree decl
)
278 /* Declare module_ctor (). */
279 TREE_PUBLIC (decl
) = 1;
280 DECL_ARTIFICIAL (decl
) = 1;
281 DECL_VISIBILITY (decl
) = VISIBILITY_DEFAULT
;
282 DECL_VISIBILITY_SPECIFIED (decl
) = 1;
283 DECL_STATIC_CONSTRUCTOR (decl
) = 1;
287 /* BuildConstLiteralNumber - returns a GCC TREE built from the
288 string, str. It assumes that, str, represents a legal number in
289 Modula-2. It always returns a positive value. */
292 m2decl_BuildConstLiteralNumber (location_t location
, const char *str
,
293 unsigned int base
, bool issueError
)
297 bool overflow
= m2expr_OverflowZType (location
, str
, base
, issueError
);
299 value
= m2expr_GetIntegerZero (location
);
302 overflow
= m2expr_StrToWideInt (location
, str
, base
, wval
, issueError
);
304 value
= m2expr_GetIntegerZero (location
);
307 value
= wide_int_to_tree (m2type_GetM2ZType (), wval
);
308 overflow
= m2expr_TreeOverflow (value
);
311 if (issueError
&& overflow
)
312 error_at (location
, "constant %qs is too large", str
);
313 return m2block_RememberConstant (value
);
316 /* BuildCStringConstant - creates a string constant given a, string,
320 m2decl_BuildCStringConstant (const char *string
, int length
)
322 tree elem
, index
, type
;
324 /* +1 ensures that we always nul terminate our strings. */
325 elem
= build_type_variant (char_type_node
, 1, 0);
326 index
= build_index_type (build_int_cst (integer_type_node
, length
+ 1));
327 type
= build_array_type (elem
, index
);
328 return m2decl_BuildStringConstantType (length
+ 1, string
, type
);
331 /* BuildStringConstant - creates a string constant given a, string,
335 m2decl_BuildStringConstant (const char *string
, int length
)
337 tree elem
, index
, type
;
339 elem
= build_type_variant (char_type_node
, 1, 0);
340 index
= build_index_type (build_int_cst (integer_type_node
, length
));
341 type
= build_array_type (elem
, index
);
342 return m2decl_BuildStringConstantType (length
, string
, type
);
343 // maybe_wrap_with_location
348 m2decl_BuildPtrToTypeString (location_t location
, const char *string
, tree type
)
350 if ((string
== NULL
) || (strlen (string
) == 0))
351 return m2convert_BuildConvert (location
, type
,
352 m2decl_BuildIntegerConstant (0),
354 return build_string_literal (strlen (string
), string
);
358 /* BuildIntegerConstant - return a tree containing the integer value. */
361 m2decl_BuildIntegerConstant (int value
)
367 return integer_zero_node
;
369 return integer_one_node
;
372 return m2block_RememberConstant (
373 build_int_cst (integer_type_node
, value
));
377 /* BuildStringConstantType - builds a string constant with a type. */
380 m2decl_BuildStringConstantType (int length
, const char *string
, tree type
)
382 tree id
= build_string (length
, string
);
384 TREE_TYPE (id
) = type
;
385 TREE_CONSTANT (id
) = TRUE
;
386 TREE_READONLY (id
) = TRUE
;
387 TREE_STATIC (id
) = TRUE
;
389 return m2block_RememberConstant (id
);
392 /* GetBitsPerWord - returns the number of bits in a WORD. */
395 m2decl_GetBitsPerWord (void)
397 return BITS_PER_WORD
;
400 /* GetBitsPerInt - returns the number of bits in a INTEGER. */
403 m2decl_GetBitsPerInt (void)
405 return INT_TYPE_SIZE
;
408 /* GetBitsPerBitset - returns the number of bits in a BITSET. */
411 m2decl_GetBitsPerBitset (void)
413 return SET_WORD_SIZE
;
416 /* GetBitsPerUnit - returns the number of bits in a UNIT. */
419 m2decl_GetBitsPerUnit (void)
421 return BITS_PER_UNIT
;
424 /* m2decl_GetDeclContext - returns the DECL_CONTEXT of tree, t. */
427 m2decl_GetDeclContext (tree t
)
429 return DECL_CONTEXT (t
);
432 #include "gt-m2-m2decl.h"