Return the type previously defined for S. Use POS to report errors.
@verbatim
If we did not find a typedef registered, generate a TYPE_UNDEFINED
type for regular type identifiers. If the type identifier S is a
template instantiation, however, we treat it as a user defined
type.
FIXME, this is actually a limitation in gengtype. Supporting
template types and their instances would require keeping separate
track of the basic types definition and its instances. This
essentially forces all template classes in GC to be marked
{
error_at_line (pos, "duplicate definition of '%s %s'",
isunion ? "union" : "struct", s->u.s.tag);
error_at_line (&s->u.s.line, "previous definition here");
}
s->kind = kind; s->u.s.tag = name; s->u.s.line = *pos; s->u.s.fields = fields; s->u.s.opt = o; s->u.s.bitmap = bitmap; if (s->u.s.lang_struct) s->u.s.lang_struct->u.s.bitmap |= bitmap; s->u.s.base_class = base_class; if (base_class) add_subclass (base_class, s);
return s; }
/**
Return the previously-defined structure or union with tag NAME,
or a new empty structure or union if none was defined previously.
The KIND of structure must be one of TYPE_STRUCT, TYPE_UNION or
TYPE_USER_STRUCT.
Return the previously-defined parameterized structure for structure
T and parameters PARAM, or a new parameterized empty structure or
union if none was defined previously.
Return a scalar type with name NAME.
Return a pointer to T.
Return an array of length LEN.
Return a string options structure with name NAME and info INFO.
NEXT is the next option in the chain.
Create a type options structure with name NAME and info INFO. NEXT
is the next option in the chain.
Create a nested pointer options structure with name NAME and info
INFO. NEXT is the next option in the chain.
Return an options structure for a "nested_ptr" option.
Add a variable named S of type T with options O defined at POS,
to `variables'.
Most-general structure field creator.
Create a field that came from the source code we are scanning,
i.e. we have a 'struct fileloc', and possibly options; also,
adjust_field_type should be called.
Create a fake field with the given type and name. NEXT is the next
field in the chain.
Like create_field, but the field is only valid when condition COND
is true.
Create a fake union type with a single nameless field of type TYPE.
The field has a tag of "1". This allows us to make the presence
of a field of type TYPE depend on some boolean "desc" being true.
Create the field and give it the new fake union type. Add a "desc"
tag that specifies the condition under which the field is valid.
Reverse a linked list of 'struct pair's in place.
We don't care how long a CONST_DOUBLE is.
We don't want to see codes that are only for generator files.
We also need codes and names for insn notes (not register notes).
Note that we do *not* bias the note values here.
We must allocate one more entry here, as we use NOTE_INSN_MAX as the
default field for line number notes.
Generate the contents of the rtx_next array. This really doesn't belong
in gengtype at all, but it's needed for adjust_field_rtx_def.
Write out the contents of the rtx_next array.
Handle `special("rtx_def")'. This is a special case for field
`fld' of struct rtx_def, which is an array of unions whose values
are based in a complex way on the type of RTL.
NOTE_INSN_MAX is used as the default field for line
number notes.
Create a type to represent the various forms of SYMBOL_REF_DATA.
Add the "block_sym" field if SYMBOL_REF_HAS_BLOCK_INFO_P
holds.
Handle `special("tree_exp")'. This is a special case for
field `operands' of struct tree_exp, which although it claims to contain
pointers to trees, actually sometimes contains pointers to RTL too.
Passed T, the old type of the field, and OPT its options. Returns
a new type for the field.
Perform any special processing on a type T, about to become the type
of a field. Return the appropriate type for the field.
At present:
- Converts pointer-to-char, with no length parameter, to TYPE_STRING;
- Similarly for arrays of pointer-to-char;
- Converts structures for which a parameter is provided to
TYPE_PARAM_STRUCT;
- Handles "special" options.
Handle OPT for set_gc_used_type.
Set the gc_used field of T to LEVEL, and handle the types it references.
If ALLOWED_UNDEFINED_TYPES is true, types of kind TYPE_UNDEFINED
are set to GC_UNUSED. Otherwise, an error is emitted for
TYPE_UNDEFINED types. This is used to support user-defined
template types with non-type arguments.
For instance, when we parse a template type with enum arguments
(e.g. MyType<AnotherType, EnumValue>), the parser created two
artificial fields for 'MyType', one for 'AnotherType', the other
one for 'EnumValue'.
At the time that we parse this type we don't know that 'EnumValue'
is really an enum value, so the parser creates a TYPE_UNDEFINED
type for it. Since 'EnumValue' is never resolved to a known
structure, it will stay with TYPE_UNDEFINED.
Since 'MyType' is a TYPE_USER_STRUCT, we can simply ignore
'EnumValue'. Generating marking code for it would cause
compilation failures since the marking routines assumes that
'EnumValue' is a type.
Anything pointing to a base class might actually be pointing
to a subclass.
Set the gc_used fields of all the types pointed to by VARIABLES.
File mapping routines. For each input file, there is one output .c file
(but some output files have many input files), and there is one .h file
for the whole build.
Output file handling.
Create and return an outf_p for a new file for NAME, to be called
ONAME.
Print, like fprintf, to O.
N.B. You might think this could be implemented more efficiently
with vsnprintf(). Unfortunately, there are C libraries that
provide that function but without the C99 semantics for its return
value, making it impossible to know how much space is required.
In plugin mode, the O could be a NULL pointer, so avoid crashing
in that case.
Open the global header file and the language-specific header files.
gtype-desc.c is a little special, so we create it here.
The order of files here matters very much.
Make sure we handle "cfun" specially.
For INPF an input file, return the real basename of INPF, with all
the directory components skipped.
For INPF a filename, return the relative path to INPF from
$(srcdir) if the latter is a prefix in INPF, NULL otherwise.
For INPF an input_file, return the relative path to INPF from
$(srcdir) if the latter is a prefix in INPF, or the real basename
of INPF otherwise.
For F a filename, return the lang_dir_names relative index of the language
directory that is a prefix in F, if any, -1 otherwise.
For INPF an input file, return the name of language directory where
F is located, if any, NULL otherwise.
Get the relative path to INPF from $(srcdir) and find the
language by comparing the prefix with language directory names.
If INPF is not even srcdir relative, no point in looking
further.
The gt- output file name for INPF.
Cook up an initial version of the gt- file name from the file real
basename and the language name, if any.
Then replace all non alphanumerics characters by '-' and change the
extension to ".h". We expect the input filename extension was at least
one character long.
Each input_file has its associated output file outf_p. The
association is computed by the function
get_output_file_with_visibility. The associated file is cached
inside input_file in its inpoutf field, so is really computed only
once. Associated output file paths (i.e. output_name-s) are
computed by a rule based regexp machinery, using the files_rules
array of struct file_rule_st. A for_name is also computed, giving
the source file name for which the output_file is generated; it is
often the last component of the input_file path.
Signature of actions in file rules.
File rule action handling *.h files.
File rule action handling *.c files.
The prefix in our regexp-s matching the directory.
The array of our rules governing file name generation. Rules order
matters, so change with extreme care!
The general rule assumes that files in subdirectories belong to a
particular front-end, and files not in subdirectories are shared.
The following rules deal with exceptions - files that are in
subdirectories and yet are shared, and files that are top-level,
but are not shared.
the c-family/ source directory is special.
Both c-lang.h & c-tree.h gives gt-c-c-decl.h for c-decl.c !
cp/cp-tree.h gives gt-cp-tree.h for cp/tree.c !
cp/decl.h & cp/decl.c gives gt-cp-decl.h for cp/decl.c !
cp/name-lookup.h gives gt-cp-name-lookup.h for cp/name-lookup.c !
cp/parser.h gives gt-cp-parser.h for cp/parser.c !
objc/objc-act.h gives gt-objc-objc-act.h for objc/objc-act.c !
objc/objc-map.h gives gt-objc-objc-map.h for objc/objc-map.c !
General cases. For header *.h and source *.c or *.cc files, we
* need special actions to handle the language.
Source *.c files are using get_file_gtfilename to compute their
output_name and get_file_basename to compute their for_name
through the source_dot_c_frul action.
Source *.cc files are using get_file_gtfilename to compute their
output_name and get_file_basename to compute their for_name
through the source_dot_c_frul action.
Common header files get "gtype-desc.c" as their output_name,
* while language specific header files are handled specially. So
* we need the header_dot_h_frul action.
Mandatory null last entry signaling end of rules.
Special file rules action for handling *.h header files. It gives
"gtype-desc.c" for common headers and corresponding output
files for language-specific header files.
The header is language specific. Given output_name &
for_name remains unchanged. The base_files array gives the
outf_p.
The header is common to all front-end languages. So
output_name is "gtype-desc.c" file. The calling function
get_output_file_with_visibility will find its outf_p.
Special file rules action for handling *.c source files using
* get_file_gtfilename to compute their output_name and
* get_file_basename to compute their for_name. The output_name is
* gt-<LANG>-<BASE>.h for language specific source files, and
* gt-<BASE>.h for common source files.
Utility function for get_output_file_with_visibility which returns
* a malloc-ed substituted string using TRS on matching of the FILNAM
* file name, using the PMATCH array.
A double dollar $$ is substituted by a single verbatim
dollar, but who really uses dollar signs in file
paths?
Handle $0 $1 ... $9 by appropriate substitution.
This can happen only when files_rules is buggy!
Always skip the character after the dollar.
An output file, suitable for definitions, that can see declarations
made in INPF and is linked into every language that uses INPF.
Since the result is cached inside INPF, that argument cannot be
declared constant, but is "almost" constant.
This can happen when we need a file with visibility on a
structure that we've never seen. We have to just hope that it's
globally visible.
The result is cached in INPF, so return it if already known.
In plugin mode, return NULL unless the input_file is one of the
plugin_files.
Try each rule in sequence in files_rules until one is triggered.
Compile the regexpr lazily.
The regular expression compilation fails only when
file_rules is buggy.
Match the regexpr and trigger the rule if matched.
We have exactly ten pmatch-s, one for each $0, $1, $2,
$3, ... $9.
Invoke our action routine.
If the action routine returned something, give it back
immediately and cache it in inpf.
The rule matched, and had no action, or that action did
not return any output file but could have changed the
output_name or for_name. We break out of the loop on the
files_rules.
The regexpr did not match.
This should not be possible, and could only happen if the
files_rules is incomplete or buggy.
Look through to see if we've ever seen this output filename
before. If found, cache the result in inpf.
If not found, create it, and cache it in inpf.
The name of an output file, suitable for definitions, that can see
declarations made in INPF and is linked into every language that
uses INPF.
Check if existing file is equal to the in memory buffer.
Copy the output to its final destination,
but don't unnecessarily change modification times.
Back up the old version of the output file gt-FOO.c as
BACKUPDIR/gt-FOO.c~ if we have a backup directory.
output file remains unchanged.
For scalars and strings, given the item in 'val'.
For structures, given a pointer to the item in 'val'.
For misc. pointers, given the item in 'val'.
Parameters for write_types.
Parameters for walk_type.
Given a string TYPE_NAME, representing a C++ typename, return a valid
pre-processor identifier to use in a #define directive. This replaces
special characters used in C++ identifiers like '>', '<' and ':' with
'_'.
If no C++ special characters are found in TYPE_NAME, return
TYPE_NAME. Otherwise, return a copy of TYPE_NAME with the special
characters replaced with '_'. In this case, the caller is
responsible for freeing the allocated string.
Print a mangled name representing T to OF.
For references to classes within an inheritance hierarchy,
only ever reference the ultimate base class, since only
it will have gt_ functions.
Print PARAM to D->OF processing escapes. D->VAL references the
current object, D->PREV_VAL the object containing the current
object, ONAME is the name of the option and D->LINE is used to
print error messages.
Call D->PROCESS_FIELD for every field (or subfield) of D->VAL,
which is of type T. Write code to D->OF to constrain execution (at
the point that D->PROCESS_FIELD is called) to the appropriate
cases. Call D->PROCESS_FIELD on subobjects before calling it on
pointers to those objects. D->PREV_VAL lists the objects
containing the current object, D->OPT is a list of options to
apply, D->INDENT is the current indentation level, D->LINE is used
to print error messages, D->BITMAP indicates which languages to
print the structure for, and D->PARAM is the current parameter
(from an enclosing param_is option).
If a pointer type is marked as "atomic", we process the
field itself, but we don't walk the data that they point to.
There are two main cases where we walk types: to mark
pointers that are reachable, and to relocate pointers when
writing a PCH file. In both cases, an atomic pointer is
itself marked or relocated, but the memory that it points
to is left untouched. In the case of PCH, that memory will
be read/written unchanged to the PCH file.
Try to unswitch loops (see PR53880).
If it's an array of scalars, we optimize by not generating
any code.
When walking an array, compute the length and store it in a
local variable before walking the array elements, instead of
recomputing the length expression each time through the loop.
This is necessary to handle tcc_vl_exp objects like CALL_EXPR,
where the length is stored in the first array element,
because otherwise that operand can get overwritten on the
first iteration.
Some things may also be defined in the structure's options.
We have a "desc" option on a struct, signifying the
base class within a GC-managed inheritance hierarchy.
The current code specialcases the base class, then walks
into subclasses, recursing into this routine to handle them.
This organization requires the base class to have a case in
the switch statement, and hence a tag value is mandatory
for the base class. This restriction could be removed, but
it would require some restructing of this code.
Add cases to handle subclasses.
Ensure that if someone forgets a "tag" option that we don't
silent fail to traverse that subclass's fields.
End of the switch statement
process_field routine for marking routines.
The current type is a pointer to a scalar (so not
considered like a pointer to instances of user defined
types) and we are seeing it; it means we must be even
more careful about the second argument of the
SUBFIELD_MARKER_ROUTINE call. That argument must
always be the instance of the type for which
write_func_for_structure was called - this really is
what the function SUBFIELD_MARKER_ROUTINE expects.
That is, it must be an instance of the ORIG_S type
parameter of write_func_for_structure. The convention
is that that argument must be "x" in that case (as set
by write_func_for_structure). The problem is, we can't
count on d->prev_val[3] to be always set to "x" in that
case. Sometimes walk_type can set it to something else
(to e.g cooperate with write_array when called from
write_roots). So let's set it to "x" here then.
If F is a user-defined type and the field is not a
pointer to the type, then we should not generate the
standard pointer-marking code. All we need to do is call
the user-provided marking function to process the fields
of F.
Return an output file that is suitable for definitions which can
reference struct S
This is a hack, and not the good kind either.
The call to get_output_file_with_visibility may update fn by
caching its result inside, so we need the CONST_CAST.
Returns the specifier keyword for a string or union type S, empty string
otherwise.
Emits a declaration for type TY (assumed to be a union or a
structure) on stream OUT.
Write on OF the name of the marker function for structure S. PREFIX
is the prefix to use (to distinguish ggc from pch markers).
Write on OF a user-callable routine to act as an entry point for
the marking routine for S, generated by write_func_for_structure.
PREFIX is the prefix to use to distinguish ggc and pch markers.
Parameterized structures are not supported in user markers. There
is no way for the marker function to know which specific type
to use to generate the call to the void * entry point. For
instance, a marker for struct htab may need to call different
routines to mark the fields, depending on the paramN_is attributes.
A user-defined marker that accepts 'struct htab' as its argument
would not know which variant to call. Generating several entry
points accepting 'struct htab' would cause multiply-defined
errors during compilation.
ALIAS_OF is set if ORIG_S is marked "ptr_alias". This means that
we do not generate marking code for ORIG_S here. Instead, a
forwarder #define in gtype-desc.h will cause every call to its
marker to call the target of this alias.
However, we still want to create a user entry code for the
aliased type. So, if ALIAS_OF is set, we only generate the
user-callable marker function.
Write a function to mark all the fields of type S on OF. PREFIX
and D are as in write_user_marking_functions.
Emit the user-callable functions needed to mark all the types used
by the user structure S. PREFIX is the prefix to use to
distinguish ggc and pch markers. D contains data needed to pass to
walk_type when traversing the fields of a type.
For every type T referenced by S, two routines are generated: one
that takes 'T *', marks the pointer and calls the second routine,
which just marks the fields of T.
For S, a structure that's part of ORIG_S, and using parameters
PARAM, write out a routine that:
- Takes a parameter, a void * but actually of type *S
- If SEEN_ROUTINE returns nonzero, calls write_types_process_field on each
field of S or its substructures and (in some cases) things
that are pointed to by S.
Verify that the base class has a "desc", since otherwise
the traversal hooks there won't attempt to visit fields of
subclasses such as this one.
Don't write fns for subclasses, only for the ultimate base class
within an inheritance hierarchy.
TYPE_USER_STRUCTs should not occur here. These structures
are completely handled by user code.
User structures have no fields to walk. Simply generate a call
to the user-provided structure marker.
Write out marker routines for STRUCTURES and PARAM_STRUCTS.
We first emit the macros and the declarations. Functions' code is
emitted afterwards. This is needed in plugin mode.
Do not emit handlers for derived classes; we only ever deal with
the ultimate base class within an inheritance hierarchy.
Declare the marker procedure only once.
Declare the marker procedure.
At last we emit the functions code.
Structure s is not possibly pointed to, so can be ignored.
Param structure s is not pointed to, so should be ignored.
Write out the local pointer-walking routines.
process_field routine for local pointer-walking for user-callable
routines. The difference between this and
write_types_local_process_field is that, in this case, we do not
need to check whether the given pointer matches the address of the
parent structure. This check was already generated by the call
to gt_pch_nx in the main gt_pch_p_*() function that is calling
this code.
Write a function to PCH walk all the fields of type S on OF.
D contains data needed by walk_type to recurse into the fields of S.
Emit the user-callable functions needed to mark all the types used
by the user structure S. PREFIX is the prefix to use to
distinguish ggc and pch markers. CHAIN_NEXT is set if S has the
chain_next option defined. D contains data needed to pass to
walk_type when traversing the fields of a type.
For every type T referenced by S, two routines are generated: one
that takes 'T *', marks the pointer and calls the second routine,
which just marks the fields of T.
process_field routine for local pointer-walking.
For S, a structure that's part of ORIG_S, and using parameters
PARAM, write out a routine that:
- Is of type gt_note_pointers
- Calls PROCESS_FIELD on each field of S or its substructures.
Don't write fns for subclasses, only for the ultimate base class
within an inheritance hierarchy.
User structures have no fields to walk. Simply generate a
call to the user-provided PCH walker.
Write user-callable entry points for the PCH walking routines.
Write out local marker routines for STRUCTURES and PARAM_STRUCTS.
Declare the marker procedure only once.
Declare the marker procedure.
Nonzero if S is a type for which typed GC allocators should be output.
Might T contain any non-pointer elements?
User-marked structures will typically contain pointers.
Could also check for structures that have no non-pointer
fields, but there aren't enough of those to worry about.
Mangle INPF and print it to F.
The call to get_output_file_name may indirectly update fn since
get_output_file_with_visibility caches its result inside, so we
need the CONST_CAST.
Finish off the currently-created root tables in FLP. PFX, TNAME,
LASTNAME, and NAME are all strings to insert in various places in
the resulting code.
Write the first three fields (pointer, count and stride) for
root NAME to F. V and LINE are as for write_root.
Return true if the entry could be written; return false on error.
A subroutine of write_root for writing the roots for field FIELD_NAME,
which has type FIELD_TYPE. Parameters F to EMIT_PCH are the parameters
of the caller.
If the field reference is relative to V, rather than to some
subcomponent of V, we can mark any subarrays with a single stride.
We're effectively treating the field as a global variable in its
own right.
Otherwise, any arrays nested in the structure are too complex to
handle.
Write out to F the table entry and any marker routines needed to
mark NAME as TYPE. V can be one of three values:
- null, if NAME is too complex to represent using a single
count and stride. In this case, it is an error for NAME to
contain any gc-ed data.
- the outermost array that contains NAME, if NAME is part of an array.
- the C variable that contains NAME, if NAME is not part of an array.
LINE is the line of the C source that declares the root variable.
HAS_LENGTH is nonzero iff V was a variable-length array. IF_MARKED
is nonzero iff we are building the root table for hash table caches.