1
0
mirror of https://github.com/cc65/cc65.git synced 2024-10-17 18:24:00 +00:00
Commit Graph

3228 Commits

Author SHA1 Message Date
acqn
ebae994dc9 Fixed CHECK failure when calling functions defined with repeated parameter names.
Clarified the terms "parameter" vs "argument" in FunctionParamList().
2020-08-17 20:27:57 +02:00
acqn
15f28c3a8c Fixed getting the basic raw type names. 2020-08-17 00:00:03 +02:00
acqn
11cd3e5cbd Utility for checking general datatype categories, incomplete ESU types and arrays of unknown sizes. 2020-08-17 00:00:03 +02:00
Jesse Rosenstock
1cf9404c19 Support C2X _Static_assert(expr) syntax
This makes the message in _Static_assert(expr, message) optional.

Fixes #1188.
2020-08-16 11:38:20 +02:00
Jesse Rosenstock
c4698dfd07 Use C89 semantics for integer conversions
Previously, the following rules were used for binary operators:
* If one of the values is a long, the result is long.
* If one of the values is unsigned, the result is also unsigned.
* Otherwise the result is an int.

C89 specifies the "usual arithmetic conversions" as:
* The integral promotions are performed on both operands.
* Then the following rules are applied:
  * If either operand has type unsigned long int, the other operand is
    converted to unsigned long int.
  * Otherwise, if one operand has type long int and the other has type
    unsigned int, if a long int can represent all values of an unsigned int,
    the operand of type unsigned int is converted to long int; if a long int
    cannot represent all the values of an unsigned int, both operands are
    converted to unsigned long int.
  * Otherwise, if either operand has type long int, the other operand is
    converted to long int.
  * Otherwise, if either operand has type unsigned int, the other operand is
    converted to unsigned int.
  * Otherwise, both operands have type int.
https://port70.net/~nsz/c/c89/c89-draft.html#3.2.1.5

As one example, these rules give a different result for an operator
with one long operand and one unsigned int operand.  Previously,
the result type was unsigned long.  With C89 semantics, it is just long,
since long can represent all unsigned ints.

Integral promotions convert types shorter than int to int (or unsigned int).
Both char and unsigned char are promoted to int since int can represent
all unsigned chars.
https://port70.net/~nsz/c/c89/c89-draft.html#3.2.1.1

Rename promoteint to ArithmeticConvert, since this is more accurate.

Fixes #170
2020-08-15 19:14:31 +02:00
acqn
b19bb14348 Fixed checking conflitcing declarations with external vs other linkage. 2020-08-14 18:33:54 +02:00
acqn
13ed557b92 Fixed compatibility checking of function declarations by using the composite types of them. 2020-08-14 18:33:54 +02:00
acqn
44d52935da Utility for getting the composite types of functions. 2020-08-14 18:33:54 +02:00
acqn
8a417ff039 Improved ESU declaration failure handling. 2020-08-14 18:15:31 +02:00
acqn
0dfe9ff5fe Fixed testing 'struct->field'. 2020-08-14 08:32:22 +08:00
acqn
0fa18886c0 Fixed copying structs/unions > 4 bytes. 2020-08-13 08:59:05 +02:00
acqn
03b37cf712 Fixed type comparisons of typedefs and arrays. 2020-08-12 15:04:26 +02:00
acqn
eb4464e828 Fixed type comparisons of ESU types with stricter rules. 2020-08-12 15:04:26 +02:00
acqn
fe44fe963f Disallowed empty enums. 2020-08-12 15:02:43 +02:00
acqn
97065faf1a Disallowed struct/union types of 0 size as cc65 is not ready to support them. 2020-08-12 15:02:43 +02:00
acqn
4dfc1a5ded Using a dedicated SC_FICTITIOUS flag in case of parsing errors. 2020-08-12 15:01:31 +02:00
acqn
bde5be6793 Improved error message on initializing extern variables inside functions. 2020-08-12 15:01:31 +02:00
acqn
b62b1650f5 Improved error messages on struct/union type multiple definitions. 2020-08-12 15:01:31 +02:00
acqn
fe3f726fd6 Improved incomplete enum typed diagnostics. 2020-08-12 15:01:31 +02:00
acqn
0d53806490 Avoided excess errors in incomplete struct assignment. 2020-08-12 15:01:31 +02:00
acqn
9317db6642 Slightly improved type error messages of 'op='. 2020-08-12 15:01:31 +02:00
acqn
9fcfa3fc49 Fixed full type names of functions with "empty" parameter list. 2020-08-12 15:01:31 +02:00
acqn
68d63b089d Reduced error flood raised by misplaced variable declarations. 2020-08-12 15:01:31 +02:00
acqn
0f1a5e0520 Set enum tag definition flags. 2020-08-09 22:12:36 +02:00
acqn
1dd899c7c9 Fixed non-file-scope multiple definition checking. 2020-08-09 22:12:36 +02:00
acqn
d68cd90e47 Function declaration in functions cannot have storage classes other than 'extern'. 2020-08-07 10:16:33 +02:00
acqn
43efc256f1 Changed error/warning messages not using the term 'tentative' according to PR reviews. 2020-08-07 10:16:33 +02:00
acqn
b2d3b8379c Warning about forward declaration of enum types in non-cc65 modes. 2020-08-07 10:16:33 +02:00
acqn
8cdffc1944 No storage for unsuccessfully parsed variables. 2020-08-07 10:16:33 +02:00
acqn
fdef067629 Fixed tentative definition of variables of incomplete types that may be completed later.
Tenative arrays that never get completed are now assumed each to have one element.
2020-08-07 10:16:33 +02:00
acqn
fdd120db49 Enabled to output errors and warnings about tentative definitions. 2020-08-07 10:16:33 +02:00
acqn
f59d6b8f6a Redefining enums/structs/unions of 0 size is no longer treated as declarations and thus forbidden. 2020-08-07 10:16:33 +02:00
Jesse Rosenstock
cdfc1afd89 Fix vacuous comparison warning from 0df45fe
cc65/symentry.c:306:60: warning: address of array 'Sym->Name' will always evaluate to 'true' [-Wpointer-bool-conversion]
    sprintf (TypeName, "%s %s", GetBasicTypeName (T), Sym->Name ? Sym->Name : "<unknown>");
                                                      ~~~~~^~~~ ~
2020-08-05 17:48:13 +02:00
Jesse Rosenstock
d8f9201ecd LoadExpr: Optimize <= 8-bit bit-field loads
Set CF_FORCECHAR to do as many operations as char ops as possible.
Clear high byte at the end.
2020-08-05 12:49:46 +02:00
Jesse Rosenstock
0c72647edd Remove extra ED_TestDone call
Accidentally added in #1141.
2020-08-03 12:40:58 +02:00
acqn
bae431eab0 Fixed error message of CheckedPSizeOf(). 2020-08-03 06:18:28 +02:00
acqn
d6aa446b54 Error info for loading expressions of incomplete enum types.
No more "Illegal type 0016".
2020-08-02 23:51:11 +02:00
acqn
6df4f1996b Improved diagnostics with more detailed type names. 2020-08-02 23:51:11 +02:00
acqn
11a5f0edf1 No "Statement has no effect" warnings on statements with errors. 2020-08-02 23:51:11 +02:00
acqn
7e68a24625 Clearer warning messages on unused symbols. 2020-08-02 23:51:11 +02:00
acqn
e8c2886455 Improved error messages on redefinitions of constants and bit-fields. 2020-08-02 23:51:11 +02:00
acqn
ef5a4db12e Improved warning messages on UB shifts. 2020-08-02 23:51:11 +02:00
acqn
2ab7272673 Improved warning on comparison of unsigned type < 0. 2020-08-02 23:51:11 +02:00
acqn
99ac1c46da Made errors/warnings statistic message visible when there are errors. 2020-08-02 23:51:11 +02:00
acqn
44e3080ea9 Increased upper limit of allowed errors before aborting. 2020-08-02 23:51:11 +02:00
acqn
00c16d34a4 Minor fixes for HandleSymRedefinition(). 2020-08-02 23:51:11 +02:00
acqn
80b0e57543 Changed parameter constness of TypeConversion(). 2020-08-02 18:55:46 +02:00
acqn
003d47cc8b Improved type conversion diagnostic messages.
Allowed incompatible pointer assignments with warnings.
Fixed Issue #1089.
2020-08-02 18:55:46 +02:00
acqn
d841bbe498 Utility to check for castability. 2020-08-02 18:55:46 +02:00
acqn
52051f444e Using tracked individual string buffers instead of a shared static string buffer for full type names. 2020-08-02 18:55:46 +02:00
acqn
4ccf10f3fa Utility to get full type names. 2020-08-02 18:55:46 +02:00
acqn
0df45fe2f2 Utility for getting ESU tag type symbols. 2020-08-02 18:55:46 +02:00
Oliver Schmidt
c831f40e9b Unfortunately there's no other way than using the absolute path to init the correct MSVC 2017 environment. 2020-08-02 18:44:13 +02:00
Oliver Schmidt
992596c981 Initialize MSVC 2017 environment before build. 2020-08-02 17:32:36 +02:00
Jesse Rosenstock
adda28f5c5 LoadExpr: Set CF_FORCECHAR if test is required
If we are testing, we do not need to load the high byte(s).
2020-08-02 12:31:57 +02:00
acqn
2a555d198c Changed 'switch' to 'if' according PR review comments. 2020-08-02 12:28:11 +02:00
acqn
30fd8592ae Avoid internal errors when using function-type objects in expressions. 2020-08-02 12:28:11 +02:00
acqn
e526cbbff6 Fixed handling multiple storage specifiers in one declaration. 2020-08-02 02:20:25 +02:00
Oliver Schmidt
e1043fac12 Adjusted to https://github.com/cc65/cc65/pull/1124. 2020-08-01 10:56:05 +02:00
Jesse Rosenstock
9c70bd44a6 Clarify comment about large shift
This is to avoid overflow on host platform.
2020-07-31 19:33:28 +02:00
Jesse Rosenstock
847982c6bf Handle bit-field test after shift/mask
Previously, bit-field tests were incorrectly combined with load in
`if (x.bitfield)`.  Delay the test until after the shift/mask
is done.  Still combine tests with load if no shift/mask is required.

Fixes #1139
2020-07-31 19:33:28 +02:00
Jesse Rosenstock
d0c7108dcf Change copyright notice to "The cc65 Authors" 2020-07-30 19:17:11 +02:00
Jesse Rosenstock
3df6c383c0 Add support for static_assert
Add C11's _Static_assert and static_assert macro.

This is like #error, but is handled at a later stage
of translation, so it is possible to check sizes of
types, values of enums, etc.

https://en.cppreference.com/w/c/language/_Static_assert
https://port70.net/~nsz/c/c11/n1570.html#6.7.10
2020-07-30 19:17:11 +02:00
Jesse Rosenstock
2d5fd0fc63 Use char ops if possible for bit-field loads
Set CF_FORCECHAR and change type to char once we have
shifted into a char.

This saves some unnecessary ldx #0 instructions.
2020-07-30 14:59:23 +02:00
acqn
e38f601fcc Fixed padding at the ends of structs with bit-fields. 2020-07-30 08:38:24 +02:00
acqn
8a511bb63d Fixed nested array initializers. 2020-07-30 08:38:24 +02:00
acqn
9075a853dc Allows one trailing comma before the closing curly of a struct/union initializer. 2020-07-30 08:38:24 +02:00
acqn
25d10d9d9a Fixed nested struct/union initialization.
Fixed bit-fields offsets in anonymous structs.
2020-07-30 08:38:24 +02:00
acqn
d6d667a688 Improved error handling with symbol redefinitions. 2020-07-30 08:22:29 +02:00
acqn
92de4fa0d0 Enabled to recognize labels when parsing local variable declarations. 2020-07-30 08:22:29 +02:00
acqn
19c81ed866 Fixed type mask usage. 2020-07-30 08:13:23 +02:00
Jesse Rosenstock
fb9b50ff9c Move type checks before bit-field width parsing 2020-07-30 08:10:38 +02:00
Jesse Rosenstock
a2561d07f3 Remove special-case bit-field width code
cbb33f8 restricted allowed bit-field types to int,
so this is equivalent for now, but forward-compatible.

Fixes FIXME

Also move the int type check before parsing the colon.
2020-07-30 08:10:38 +02:00
Oliver Schmidt
8eab28012a
Adjusted project name. 2020-07-28 23:29:16 +02:00
acqn
cbb33f86e8 Disabled using non-int-size types to declare bit-fields. 2020-07-28 23:26:25 +02:00
acqn
c37f9f1a41 Check if the integer size is known in GetIntegerTypeMin/Max() to prevent potential misuse. 2020-07-28 23:26:25 +02:00
acqn
0f412b6beb Small fixes according to PR review. 2020-07-28 23:26:25 +02:00
acqn
7e243e0f2c Allowed using all integer types including enum and char types to define bit-fields,
but kept the currently behavior that all of them are treated as unsigned int.
2020-07-28 23:26:25 +02:00
acqn
d8184fbe54 No longer insert all enums in the global symbol table. 2020-07-28 23:26:25 +02:00
acqn
daa65199b3 Fixed underlying types of enums.
Made enumerator diagnostics more sensible.
Fixed Issue #1048 as a natural result.
2020-07-28 23:26:25 +02:00
Greg King
44c82eb1c3 Made da65 disassemble branch instructions with relative address expression operands if there's no label. 2020-07-21 18:43:32 -04:00
acqn
07e18774f7 Added spaces around '|' with regex replacement. 2020-07-21 18:23:52 +02:00
acqn
c66d0881b9 Made the enum/enumerator types clearer and improved DumpSymEntry() output. 2020-07-21 18:23:52 +02:00
acqn
18bd76bb90 Minor fixes and improvements. 2020-07-21 18:23:52 +02:00
acqn
65081aebed Made able to recognize global declarations of static arrays. Fixed Issue #975. 2020-07-21 18:23:52 +02:00
acqn
0250c87ac6 Fixed SC_* type masks by making them all bitwise-exclusive. 2020-07-21 18:23:52 +02:00
acqn
78342fa82c Fix for "auto" variables made "static" with the "-Cl" options. 2020-07-20 15:01:47 +02:00
acqn
71c2d27705 Removed an ED_IsBitField() test according to PR review. 2020-07-20 14:54:32 +02:00
acqn
2245783345 Fixed ability to do actual type conversion from bit-fields to integers. Note this doesn't try to fix the signedness issues. 2020-07-20 14:54:32 +02:00
acqn
b67b8ddd38 Disabled applying 'sizeof' to bit-fields. 2020-07-20 14:54:32 +02:00
acqn
62a6e37487 Made the code handling '&expression' slightly tidier. 2020-07-20 14:54:32 +02:00
acqn
3c52ad1d9e New utility ED_DisBitField() to make an expression no longer a bit-field. 2020-07-20 14:54:32 +02:00
Greg King
fd0a6955da Changed "IsTypeStruct() || IsTypeUnion()" expressions into shorter "IsClassStruct()" expressions.
Type-classes are groups of types that can be handled in the same way (similar syntax).
2020-07-19 14:30:22 -04:00
acqn
29c50ab25f Corrected the error message about struct/union members not found. 2020-07-19 12:57:59 +02:00
acqn
768e03a474 Small fixes and tidy-up based on PR review.
Renamed GetReplacementType() to GetStructReplacementType().
Clarified in comments that most *Struct* facilities work for unions as well.
Made it clear in some error messages with regards to structs/unions.
2020-07-19 10:58:33 +02:00
acqn
0c3e1b491f Disabled -Wstruct-param by default. 2020-07-19 10:58:33 +02:00
acqn
b45d373fd6 Fixed passing by value structs/unions <= 4 bytes in size to functions. Larger ones are forbidden for now. 2020-07-19 10:58:33 +02:00
acqn
9f67b45ea0 Fixed returning by value structs/unions <= 4 bytes in size from functions. Larger ones are forbidden for now. 2020-07-19 10:58:33 +02:00
acqn
66ecc0e52c New utility to get the proper replacement type for passing structs/unions by value.
New utility to get basic type names such as 'struct', 'union' and so on.
2020-07-19 10:58:33 +02:00
acqn
333fa97326 Whitespaces/newlines fixes. 2020-07-18 12:54:29 +02:00
acqn
9198b3be00 Fixed '&function' and '&array'. 2020-07-18 12:54:29 +02:00
acqn
d23b577331 More compiler flags on address types to match the location types of expressions. 2020-07-18 12:54:29 +02:00
acqn
2108489523 Fix for Issue #1075 and #1077. 2020-07-18 12:54:29 +02:00
acqn
727040d1ac Comment fix. 2020-07-12 12:35:42 +02:00
acqn
7d652d42dc Added a warning on promoting a decimal constant without a 'u'/'U' suffix to unsigned long. 2020-07-12 12:35:42 +02:00
Jesse Rosenstock
f5afc75cbd ar65/LibClose: Include filename in error messages
```
ar65: Error: Problem deleting temporary library file '../lib/apple2enh.lib.temp': No such file or directory
```
is the error I'm getting with `make -j 19` when trying
to debug #1080.
2020-07-09 21:56:02 +02:00
acqn
85e73e91f8 Only enable signed div replacements with shift according to the code size factor settings.
Also with better comments.
2020-07-09 10:00:50 +02:00
acqn
09bcff0862 Added support for changing divisions by negative power-of-2 denominators into bit shifts,
and fixed #169 including the case of -2147483648 which is negative but appears positive.
2020-07-09 10:00:50 +02:00
acqn
30835e3d9d More optimized codegen for the correct cases of the Issue #169 fix. 2020-07-09 10:00:50 +02:00
acqn
e98fe04cc2 Almost fixed Issue #169. The only denominator not working right now is -2147483648. 2020-07-09 10:00:50 +02:00
Jesse Rosenstock
82c8bd6e2b Replace unary negation with subtraction
Remove MSVC pragma.
2020-07-09 09:49:24 +02:00
Jesse Rosenstock
2c16453a9f Guard MSVC pragma with ifdef _MSC_VER
Fix broken travis-ci with gcc -Werror [-Werror=unknown-pragmas].
2020-07-09 09:49:24 +02:00
Jesse Rosenstock
9e5b8d99a3 Fix MSVC build broken by #1058
MSVC complains about unary negation of unsigned, but it's
intended.  Suppress the warning.

https://github.com/cc65/cc65/pull/1058#discussion_r451757967

"Tested" with godbolt.org.
2020-07-09 09:49:24 +02:00
Jesse Rosenstock
6dc2bf1226 Rename PaddingBitWidth to PaddingBits 2020-07-08 16:46:34 +02:00
Jesse Rosenstock
9858e47dfd Pad bit-fields only to the next byte
Fixes #1054.

Previously, bit-fields followed by another field were aligned
to two bytes.  Bit-fields ending the struct were (and continue
to be) aligned only to a single byte.

```
struct s {
  unsigned int x : 4;
};

struct t {
  unsigned int x : 4;
  unsigned int y;
};
```

Before: `sizeof(struct s) == 1`, sizeof(struct t) == 4`
After: `sizeof(struct s) == 1` sizeof(struct t) == 3`
2020-07-08 16:46:34 +02:00
Jesse Rosenstock
9e881a497e Fix formatting 2020-07-08 16:45:00 +02:00
Jesse Rosenstock
c273c90bf2 Fix formatting 2020-07-08 16:45:00 +02:00
Jesse Rosenstock
527df094ca Use xrealloc in cl65
Previously, xmalloc and xfree were used.
2020-07-08 16:45:00 +02:00
Jesse Rosenstock
416adbce82 Add blank line 2020-07-08 16:44:06 +02:00
Jesse Rosenstock
021362fb75 cl65: Remove temporary .o files 2020-07-08 16:44:06 +02:00
acqn
539924249b More complete fix for Issue #1071. 2020-07-07 18:28:56 +02:00
acqn
286da30a26 Quick fix for Issue #1071. 2020-07-07 18:28:56 +02:00
Daniel Serpell
17c5504129 In Atari XEX output format, join memory areas if possible.
This makes executables shorter if two memory areas are consecutive.
2020-07-04 23:28:10 +02:00
Jesse Rosenstock
d31171164e Fix formatting 2020-06-29 14:49:36 -04:00
Jesse Rosenstock
fae25bc459 CHECK we have at most a partial byte 2020-06-29 14:49:36 -04:00
Jesse Rosenstock
f4a6d08847 Fix full bytes vs full word in comment 2020-06-29 14:49:36 -04:00
Jesse Rosenstock
a00611798d Output bit-field data as chars instead of ints
This prepares for #1058, which will pad bit-fields only to
the next byte, instead of the next sizeof(int) (two bytes).

OutputBitFieldData now outputs chars instead of ints, and
calls to this function loop until there is less than one byte
to output.  A final partial byte is written out with zero padding
as a final partial int was previously.
2020-06-29 14:49:36 -04:00
Jesse Rosenstock
90d1c89bff
Allow overlap of bit-field storage units (#1055)
* Allow overlap of bit-field storage units

Previously,
struct s {
    unsigned int x : 10;
    unsigned int y : 10;
};
had sizeof(struct s) == 4.

With this change, allow the storage units of x and y to overlap,
so sizeof(struct s) == 3, with y stored immediately after x,
with no padding between them.

An int bit-field (the only type currently supported) will still
never occupy more than two bytes.

* ParseStructInit: Fix typo and expand comment

Explain why there are at most 30, not 32 bits.

* ParseStructDecl: Rewrite AddBitFieldCall

No behavior change.

Co-authored-by: Jesse Rosenstock <jmr@users.noreply.github.com>
2020-06-27 15:02:11 +02:00
acqn
8a166ac82f Fixed register usage tracking interfered by CE_SetArg. 2020-06-22 23:23:39 +02:00
acqn
2220c58f51 If the previous insn may be skipped, we cannot simply predict the output values of the registers. 2020-06-22 23:23:39 +02:00
acqn
53eb6a948d No more duplicated stores by Opt_tosshift which could result in worse optimizations. 2020-06-22 23:23:39 +02:00
acqn
49c5cfd65b Improved fix for Issues #167 and #784 and somehow #781. 2020-06-22 23:23:39 +02:00
acqn
48d3578c24 Fixed Issue #784. 2020-06-22 23:23:39 +02:00
acqn
a7a8426a90 Just keep Lhs loads in OptStackOps and leave them to OptUnusedLoads,
whilst Rhs loads must be removed for OptStackOps to work right.
Fixed Issue #167 as well as similar issues with tosshift.
2020-06-22 23:23:39 +02:00
Jesse Rosenstock
1c2edc5434 AddBitField: Rename Width arg to BitWidth
This makes the arg consistent with the SymEntry field name.
2020-06-21 01:08:44 +02:00
Jesse Rosenstock
4afc552e17 ParseStructDecl: Make BitOffs unsigned
This makes it consistent with SymEntry and removes the need for
some casts that were added to avoid warnings about signed vs
unsigned comparison.
2020-06-21 01:07:45 +02:00
mrdudz
baa5d051e4 use same description as in the docs 2020-06-16 00:11:07 +02:00
mrdudz
349a84d972 remove superfluous TAB 2020-06-16 00:08:55 +02:00
mrdudz
98c7186221 Add description for --debug-opt-output to the --help output 2020-06-15 23:39:50 +02:00
acqn
f9204e5b6f Fixed g_addlocal codegen with long types. 2020-06-01 22:37:40 +02:00
acqn
8066cd9ace Fixed wrong case in PreDec codegen, which never seems to be in use though. 2020-06-01 22:37:40 +02:00
acqn
07a5324a81 Fixed Issue #1028 by outputing local literals when exiting the function scope. 2020-06-01 22:37:40 +02:00
acqn
68f53e69f1 Fixed Issues #420 and #919 by always outputing the code segment before the three data segments for functions. 2020-06-01 22:37:40 +02:00
acqn
33e103fdc6 Fixed Issue #1040: non-byte pointer +=/-= byte codegen bug. 2020-06-01 22:37:40 +02:00
Oliver Schmidt
555282497c Removed --lib option from cl65.
The general approach of cl65 when generating the command lines to be executed is to first put options and the put files. However, this doesn't work well with the --lib option which would rather need to be put when libraries in general are put. I opted to not add this special behavior to cl65 as
* the use case for the --lib option is _VERY_ specific
* cl65 is after all a wrapper for ordinary use cases
2020-05-30 21:03:15 +02:00
laubzega
dc4142e1a9 Minor formatting changes after review. 2020-05-29 10:00:33 +02:00
laubzega
083f3ae26b Fix for #928. 2020-05-29 10:00:33 +02:00
Greg King
f8be35b41e Fixed some typos in the "large alignment" support. 2020-05-15 21:09:02 -04:00
Chris Cacciatore
ad1eadd60d Added support for --large-alignment in ld65.
Implemented the same way as in ca65.
2020-05-15 17:54:41 -04:00
greg-king5
4ea2bfef0a Aligned comment. 2020-03-26 23:08:49 -04:00