Commit Graph

186 Commits

Author SHA1 Message Date
Stephen Heumann
a7d9d3039b Initialize arrays from strings with a pc_mov operation.
This is smaller and more efficient than the previous code that called memcpy(). It also avoids a theoretical issue if the user's code included an incompatible definition of memcpy.
2022-12-05 18:00:56 -06:00
Stephen Heumann
736e7575cf Fix issues with type conversions in static initialization.
*Initialization of floating-point variables from unsigned long expressions with value > LONG_MAX would give the wrong value.
*Initialization of floating-point variables from (unsigned) long long expressions would give the wrong value.
*Initialization of _Bool variables should give 0 or 1, as per the usual rules for conversion to _Bool.
*Initialization of integer variables from floating-point expressions should be allowed, applying the usual conversions.
2022-12-04 16:36:16 -06:00
Stephen Heumann
36c70f9107 Move ResolveForwardReference call to apply to the field being initialized. 2022-12-04 16:23:33 -06:00
Stephen Heumann
945d5ce855 Generate calls to ~ZERO to initialize large numbers of zero bytes.
There is a tradeoff of code size vs. speed, since a sequence of STZ instructions is faster than a call to ~ZERO but could be quite large for a big array or struct. We now use ~ZERO for initializations of over 50 bytes to avoid excessive code bloat; the exact number chosen is somewhat arbitrary.
2022-12-03 15:30:31 -06:00
Stephen Heumann
28e119afb1 Rework static initialization to support new-style initializer records.
Static initialization of arrays/structs/unions now essentially "executes" the initializer records to fill in a buffer (and keep track of relocations), then emits pcode to represent that initialized state. This supports overlapping and out-of-order initializer records, as can be produced by designated initialization.
2022-12-02 21:55:57 -06:00
Stephen Heumann
48efd462ef Allow designated initialization of fields named the same as typedefs.
They are in separate name spaces, so this should be permitted.
2022-12-01 14:09:03 -06:00
Stephen Heumann
8ad58b0de7 Report an error for dual commas at end of struct/union initializer.
This covers things like:

struct {int a,b;} u = {1,2,,};
2022-11-30 19:07:38 -06:00
Stephen Heumann
c1a188aa95 Add some comments in initialization code. 2022-11-30 18:55:43 -06:00
Stephen Heumann
51951721c5 Simplify Fill procedure.
In the current design, it only needs to fill in a certain number of bytes, not a specific type.
2022-11-30 18:37:28 -06:00
Stephen Heumann
94584b0f05 Give error for arrays that are still 0 size after initialization.
This prohibits empty initializers ({}) for arrays of unknown size, consistent with C23 requirements. Previous versions of C did not allow empty initializers at all, but ORCA/C historically did in some cases, so this patch still allows them for structs/unions/arrays of known size.
2022-11-30 17:57:21 -06:00
Stephen Heumann
e7940db4c8 Allow initializers where a string literal begins a longer expression.
This is needed to support cases like:

char s[5] = {"abc"[1]};
2022-11-29 21:15:42 -06:00
Stephen Heumann
1f468c437f Set errorFound to true for most errors during initialization. 2022-11-29 13:20:30 -06:00
Stephen Heumann
ac741e26ab Allow nested auto structs/unions to be initialized with an expression of the same type.
When the expression is initially parsed, we do not necessarily know whether it is the initializer for the struct/union or for its first member. That needs to be determined based on the type. To support that, a new function is added to evaluate the expression separately from using it to initialize an object.
2022-11-29 13:19:59 -06:00
Stephen Heumann
c58d84689a Explicitly set disp for every array element.
This is needed to properly deal with arrays of structures with unnamed bit-fields at the end.
2022-11-28 22:11:39 -06:00
Stephen Heumann
4a8b5b25c7 Use a variable to indicate storage duration for initialization. 2022-11-28 21:59:08 -06:00
Stephen Heumann
50e3a8ea30 Avoid dereferencing nil. 2022-11-28 21:44:30 -06:00
Stephen Heumann
bde70e0885 Simplify fill-with-zeros logic.
It now just fills on levels with braces (or at the end of a string).
2022-11-28 21:41:05 -06:00
Stephen Heumann
dc305a86b2 Add flag to suppress printing of put-back tokens with #pragma expand.
This is currently used in a couple places in the designated initializer code (solving the problem with #pragma expand in the last commit). It could probably be used elsewhere too, but for now it is not.
2022-11-28 21:22:56 -06:00
Stephen Heumann
39250629bd Support designated initialization of anonymous member fields.
As noted previously, there is some ambiguity in the standards about how anonymous structs/unions participate in initialization. ORCA/C follows the model that they do participate as structs or unions, and designated initialization of them is implemented accordingly.

This currently has a slight issue in that extra copies of the anonymous member field name will be printed in #pragma expand output.
2022-11-28 20:55:47 -06:00
Stephen Heumann
4621336c3b Give anonymous structs/unions unique internal names.
This will help deal with initialization of them.
2022-11-28 20:47:13 -06:00
Stephen Heumann
a3c4eeb8f6 Rework bit-field initialization.
This generally simplifies things, and always generates individual initializer records for each explicit initialization of a bit-field (which was previously done for automatic initialization, but not static).

This should work correctly for automatic initialization, but needs corresponding code changes in GenSymbols for static initialization.
2022-11-28 18:49:49 -06:00
Stephen Heumann
adfa7c04c1 Support for filling uninitialized data in structs/unions during initialization. 2022-11-28 18:46:40 -06:00
Stephen Heumann
c261e14d56 Basic support for mixing array and struct designators. 2022-11-27 23:54:24 -06:00
Stephen Heumann
250a6361c1 Basic code to handle struct/union designators.
This does not deal with filling yet.
2022-11-27 23:37:22 -06:00
Stephen Heumann
def9e56e8e Fill logic for when to fill uninitialized data with zeros.
This could maybe be simplified to just fill on levels with braces, but I want to consider that after implementing designated initializers for structs and unions.
2022-11-27 17:30:36 -06:00
Stephen Heumann
6260a27b11 Use 16-bit operations to zero out a range of bytes. 2022-11-27 16:49:43 -06:00
Stephen Heumann
58d8edf1ee Handle filling of array elements without explicit initializers.
At this point, designated initializers for arrays are at least largely working.
2022-11-27 16:48:58 -06:00
Stephen Heumann
aa6b82a136 Ensure array designators are processed at the level with braces. 2022-11-26 23:03:20 -06:00
Stephen Heumann
5df94c953e Fix handling of initializer counts in AutoInit.
This was broken by the previous changes to it.
2022-11-26 21:09:53 -06:00
Stephen Heumann
335e8be75e Rename the procedure for initializing one element of an auto variable.
"InitializeOneElement" is more descriptive of what it does now. We also skip passing the variable, which is always the same.
2022-11-26 20:46:24 -06:00
Stephen Heumann
5f8a6baa94 Get rid of an unnecessary field in initializer records.
The "isStructOrUnion" information can now be determined simply by the type in the record.
2022-11-26 20:29:31 -06:00
Stephen Heumann
968844fb38 Make auto initialization use the type and disp in initializer record.
This simplifies the code a good bit, as well as enabling out-of-order initialization using designated initializers.
2022-11-26 20:24:33 -06:00
Stephen Heumann
d1edc8821d Record the type being initialized in auto initializer records. 2022-11-26 19:58:01 -06:00
Stephen Heumann
cd9931a60c Record displacement from start of object in initializer records.
The idea (not yet implemented) is to use this to support out-of-order initialization. For automatic variables, we can just initialize the subobjects in the order that initializers appear. For static variables, we will eventually need to reorder the initializers in order, but this can be done based on their recorded displacements.
2022-11-26 19:27:17 -06:00
Stephen Heumann
8cfc14b50a Rename itype field of initializerRecord to basetype. 2022-11-26 15:45:26 -06:00
Stephen Heumann
b6d3dfb075 Designated initializers for arrays, part 1.
This can parse designated initializers for arrays, but does not create proper initializer records for them.
2022-11-26 15:22:58 -06:00
Stephen Heumann
740468f75c Avoid generating invalid .sym files if header ends with a partial prototyped function decl.
This could happen because the nested calls to DoDeclaration for the parameters would set inhibitHeader to false.
2022-11-26 14:20:58 -06:00
Stephen Heumann
2bf3862e5d Avoid generating invalid .sym files if header ends with a partial declaration.
The part of the declaration within the header could be ignored on subsequent compilations using the .sym file, which could lead to errors or misbehavior.

(This also applies to headers that end in the middle of a _Static_assert(...) or segment directive.)
2022-11-26 00:18:57 -06:00
Stephen Heumann
5500833180 Record which anon struct/union an anonymous member field came from.
This is preparatory to supporting designated initializers.

Any struct/union type with an anonymous member now forces .sym file generation to end, since we do not have a scheme for serializing this information in a .sym file. It would be possible to do so, but for now we just avoid this situation for simplicity.
2022-11-25 22:32:59 -06:00
Stephen Heumann
3f450bdb80 Support "inline" function definitions without static or extern.
This is a minimal implementation that does not actually inline anything, but it is intended to implement the semantics defined by the C99 and later standards.

One complication is that a declaration that appears somewhere after the function body may create an external definition for a function that appeared to be an inline definition when it was defined. To support this while preserving ORCA/C's general one-pass compilation strategy, we generate code even for inline definitions, but treat them as private and add the prefix "~inline~" to the name. If they are "un-inlined" based on a later declaration, we generate a stub with external linkage that just jumps to the apparently-inline function.
2022-11-19 23:04:22 -06:00
Stephen Heumann
d96a5f86f9 Do not force function type info to be in the global pool.
This should no longer be necessary, because functions are not forced to be in the global symbol table.
2022-11-07 21:41:30 -06:00
Stephen Heumann
202ed3b514 Require a declarator after comma in declarations.
This gives an error for code like "int x,;".
2022-11-07 20:00:23 -06:00
Stephen Heumann
82b2944eb8 Give an error if a function is defined multiple times. 2022-11-06 20:54:53 -06:00
Stephen Heumann
d3ba8b5551 Rework handling of scopes created for function declarators.
This is preparatory to other changes.
2022-11-05 21:13:44 -05:00
Stephen Heumann
986a283540 Simplify some code in DoDeclaration and improve error detection.
This detects errors in the following cases that were previously missed:

* A function declaration and definition being part of the same overall declaration, e.g.:
void f(void), g(void) {}

* A function declaration (not definition) with no declaration specifiers, e.g.:
f(void);

(Function definitions with no declaration specifiers continue to be accepted by default, consistent with C90 rules.)
2022-11-05 20:20:04 -05:00
Stephen Heumann
7d6b732d23 Simplify some declaration-processing logic.
This should not cause any functional change.
2022-11-01 18:43:44 -05:00
Stephen Heumann
f31b5ea1e6 Allow "extern inline" functions.
A function declared "inline" with an explicit "extern" storage class has the same semantics as if "inline" was omitted. (It is not an inline definition as defined in the C standards.) The "inline" specifier suggests that the function should be inlined, but it is legal to just ignore it, as we already do for "static inline" functions.

Also add a test for the inline function specifier.
2022-10-29 19:43:57 -05:00
Stephen Heumann
f54d0e1854 Require that main have no function specifiers.
This enforces a constraint in the C standards (for a hosted environment).
2022-10-29 18:36:51 -05:00
Stephen Heumann
65ec29ee3e Use 32-bit representation for line numbers.
C99 and later specify that line numbers set via #line can be up to 2147483647, so they need to be represented as (at least) a 32-bit value.
2022-10-22 21:46:12 -05:00
Stephen Heumann
bdf212ec6b Remove support for separate . . . as equivalent to a ... token.
The scanner has been updated so that ... should always get recognized as a single token, so this is no longer necessary as a workaround. Any code that actually uses separate . . .  is non-standard and will need to be changed.
2022-10-19 18:14:14 -05:00