diff --git a/doc/internals-target.txt b/doc/internals-target.txt index 023b863..98b47eb 100644 --- a/doc/internals-target.txt +++ b/doc/internals-target.txt @@ -9,7 +9,7 @@ A machine target is specified by filling in a '''machine_spec''' structure, defi * machine_name: name of the target * handle_option: a function that gets to inspect options passed to nesc1 and take appropriate action (example: the '''self''' target adjusts double alignment based on the -malign-double gcc flag). * big_endian: must be true for big-endian targets, false for little-endian ones -* tptr, tfloat, tdouble, tlong_double, tshort, tint, tlong, tlong_long: size and alignment of the corresponding C types. +* tptr, tfloat, tdouble, tlong_double, tshort, tint, tlong, tlong_long, t_Bool: size and alignment of the corresponding C types. * int1_align, int2_align, int4_align, int8_align: with gcc, you can ask for specific size ints (see gcc's mode attribute, and the '''type_for_mode''' function in types.c). On some platforms, some of these sizes may not correspond to any of the normal basic C types, so you get to specify the alignments for those missing sizes here... * wchar_t_size: size of the wchar_t type * size_t_size: size of the size_t type (actually this should be the C type, knowing just the size can cause problems) diff --git a/nregress/c99c11/bool/BoolTest.h b/nregress/c99c11/bool/BoolTest.h new file mode 100644 index 0000000..ce59954 --- /dev/null +++ b/nregress/c99c11/bool/BoolTest.h @@ -0,0 +1,11 @@ +#ifndef __BOOL_TEST_H__ +#define __BOOL_TEST_H__ + +#include + +typedef struct { + bool a:1; + bool b; +} bool_test_args; + +#endif diff --git a/nregress/c99c11/bool/BoolTest.nc b/nregress/c99c11/bool/BoolTest.nc new file mode 100644 index 0000000..3cfd40c --- /dev/null +++ b/nregress/c99c11/bool/BoolTest.nc @@ -0,0 +1,8 @@ +#include "BoolTest.h" + +interface BoolTest { + command bool unary(const bool a); + event void unaryDone(bool result, bool arg); + command void binary(const bool_test_args args); + event void binaryDone(bool result, bool_test_args args); +} diff --git a/nregress/c99c11/bool/BoolTestM.nc b/nregress/c99c11/bool/BoolTestM.nc new file mode 100644 index 0000000..03e24b5 --- /dev/null +++ b/nregress/c99c11/bool/BoolTestM.nc @@ -0,0 +1,23 @@ +#include "BoolTest.h" + +generic module BoolTestM(bool val) { + provides interface BoolTest; +} implementation { + command bool BoolTest.unary(const bool a) { + const bool result = val ? a : !a; + signal BoolTest.unaryDone(result, a); + return result; + } + + command void BoolTest.binary(const bool_test_args args) { + const bool result = val ? args.a | args.b + : args.a ^ args.b; + signal BoolTest.binaryDone(result, args); + } + + default event void BoolTest.unaryDone(bool result, bool arg) { + } + + default event void BoolTest.binaryDone(bool result, bool_test_args args) { + } +} diff --git a/nregress/c99c11/bool/TestP.nc b/nregress/c99c11/bool/TestP.nc new file mode 100644 index 0000000..ff8ce2a --- /dev/null +++ b/nregress/c99c11/bool/TestP.nc @@ -0,0 +1,57 @@ +#include + +#include "BoolTest.h" + +module TestP { + uses interface BoolTest as Test1; + uses interface BoolTest as Test2; +} implementation { + event void Test1.unaryDone(bool result, bool arg) { + printf("Test1.unary(%d) -> %d\n", arg, result); + } + + event void Test1.binaryDone(bool result, bool_test_args args) { + printf("Test1.binary(%d, %d) -> %d\n", args.a, args.b, result); + } + + event void Test2.unaryDone(bool result, bool arg) { + printf("Test2.unary(%d) -> %d\n", arg, result); + } + + event void Test2.binaryDone(bool result, bool_test_args args) { + printf("Test2.binary(%d, %d) -> %d\n", args.a, args.b, result); + } + + int main() @C() @spontaneous() { + bool_test_args args; + bool r1, r2; + + r1 = call Test1.unary(false); + r2 = call Test1.unary(true); + if (r1 == r2) + printf("Test1.unary operation fails\n"); + args.a = args.b = false; + call Test1.binary(args); + args.b = true; + call Test1.binary(args); + args.a = true; args.b = false; + call Test1.binary(args); + args.a = args.b = true; + call Test1.binary(args); + + r1 = call Test2.unary(false); + r2 = call Test2.unary(true); + if (r1 == r2) + printf("Test2.unary operation fails\n"); + args.a = args.b = false; + call Test2.binary(args); + args.b = true; + call Test2.binary(args); + args.a = true; args.b = false; + call Test2.binary(args); + args.a = args.b = true; + call Test2.binary(args); + + return 0; + } +} diff --git a/nregress/c99c11/bool/test.nc b/nregress/c99c11/bool/test.nc new file mode 100644 index 0000000..5f843fd --- /dev/null +++ b/nregress/c99c11/bool/test.nc @@ -0,0 +1,11 @@ +#include "BoolTest.h" + +configuration test { +} implementation { + components TestP; + components new BoolTestM(1 == 1 && 0 < 1) as Test1; + components new BoolTestM(0 == 1 || 0 > 1) as Test2; + + TestP.Test1 -> Test1; + TestP.Test2 -> Test2; +} diff --git a/nregress/c99c11/run1 b/nregress/c99c11/run1 new file mode 100755 index 0000000..29709c2 --- /dev/null +++ b/nregress/c99c11/run1 @@ -0,0 +1,18 @@ +keep= +if [ -z "$NESC1" ]; then + NESC1=../../../src/nesc1 + keep=1 +fi +cd $1 +cfile=/tmp/c99c11.$$.c +exe=/tmp/c99c11.out.$$ +$NESC1 -fnesc-separator=__ test.nc -o $cfile && \ +gcc -Wall -g -o $exe $cfile && \ +$exe +ok=$? +if [ -z "$keep" ]; then + rm -f $cfile $exe +else + echo C file is $cfile, executable is $exe +fi +exit $ok diff --git a/nregress/ok/c99c11.bool.1 b/nregress/ok/c99c11.bool.1 new file mode 100644 index 0000000..2f18f4d --- /dev/null +++ b/nregress/ok/c99c11.bool.1 @@ -0,0 +1,12 @@ +Test1.unary(0) -> 0 +Test1.unary(1) -> 1 +Test1.binary(0, 0) -> 0 +Test1.binary(0, 1) -> 1 +Test1.binary(1, 0) -> 1 +Test1.binary(1, 1) -> 1 +Test2.unary(0) -> 1 +Test2.unary(1) -> 0 +Test2.binary(0, 0) -> 0 +Test2.binary(0, 1) -> 1 +Test2.binary(1, 0) -> 1 +Test2.binary(1, 1) -> 0 diff --git a/nregress/ok/c99c11.bool.2 b/nregress/ok/c99c11.bool.2 new file mode 100644 index 0000000..e69de29 diff --git a/nregress/ok/c99c11.bool.exit b/nregress/ok/c99c11.bool.exit new file mode 100644 index 0000000..573541a --- /dev/null +++ b/nregress/ok/c99c11.bool.exit @@ -0,0 +1 @@ +0 diff --git a/src/c-lex.h b/src/c-lex.h index 8a388a7..7157c40 100644 --- a/src/c-lex.h +++ b/src/c-lex.h @@ -56,6 +56,7 @@ enum rid RID_LONG, RID_SIGNED, RID_COMPLEX, + RID_BOOL, RID_LASTTYPE, RID_INLINE = RID_LASTTYPE, diff --git a/src/c-parse.gperf b/src/c-parse.gperf index 1789383..b56ab1d 100644 --- a/src/c-parse.gperf +++ b/src/c-parse.gperf @@ -50,6 +50,7 @@ __typeof__, TYPEOF, NORID __volatile, TYPE_QUAL, volatile_qualifier __volatile__, TYPE_QUAL, volatile_qualifier __builtin_va_arg, VA_ARG, NORID +_Bool, TYPESPEC, RID_BOOL asm, ASM_KEYWORD, NORID auto, SCSPEC, RID_AUTO break, BREAK, NORID diff --git a/src/machine.h b/src/machine.h index fbfb5e1..3405db1 100644 --- a/src/machine.h +++ b/src/machine.h @@ -17,7 +17,7 @@ typedef struct { size_t word_size; machine_type_spec tptr, tfloat, tdouble, tlong_double, tshort, tint, - tlong, tlong_long; + tlong, tlong_long, t_Bool; size_t int1_align, int2_align, int4_align, int8_align; size_t wchar_t_size, size_t_size; bool char_signed, wchar_t_signed; diff --git a/src/machine/avr.c b/src/machine/avr.c index 8b1b19b..431845e 100644 --- a/src/machine/avr.c +++ b/src/machine/avr.c @@ -34,6 +34,7 @@ static machine_spec avr_machine = { { 2, 1 }, /* int */ { 4, 1 }, /* long */ { 8, 1 }, /* long long (unsupported in avr-gcc) */ + { 1, 1 }, /* _Bool */ 1, 1, 1, 1, /* int1/2/4/8 align */ 2, 2, /* wchar_t, size_t size */ TRUE, TRUE, /* char, wchar_t signed */ diff --git a/src/machine/env_machine.c b/src/machine/env_machine.c index 8224aa2..2d81930 100644 --- a/src/machine/env_machine.c +++ b/src/machine/env_machine.c @@ -46,6 +46,7 @@ static machine_spec env_machine = { {2, 1}, /* int */ {4, 1}, /* long */ {8, 1}, /* long_long */ + {1, 1}, /* _Bool */ 1, 1, 1, 1, /* int1248_align */ 2, 2, /* wchar_size_size */ TRUE, TRUE, /* char_wchar_signed */ @@ -125,6 +126,7 @@ static bool scan_env_machine(machine_spec * machine, const char *envname) { "int", &(machine->tint) }, { "long", &(machine->tlong) }, { "long_long", &(machine->tlong_long) }, + { "_Bool", &(machine->t_Bool) }, { NULL, NULL } }; diff --git a/src/machine/keil.c b/src/machine/keil.c index cd46aba..ec576a4 100644 --- a/src/machine/keil.c +++ b/src/machine/keil.c @@ -98,6 +98,7 @@ static machine_spec keil_machine = { { 2, 1 }, /* int */ { 4, 1 }, /* long */ { 8, 1 }, /* long long (unsupported in avr-gcc) */ + { 1, 1 }, /* _Bool */ 1, 1, 1, 1, /* int1/2/4/8 align */ 2, 2, /* wchar_t, size_t size */ TRUE, TRUE, /* char, wchar_t signed */ diff --git a/src/machine/msp430.c b/src/machine/msp430.c index f3dcc28..bad2ec4 100644 --- a/src/machine/msp430.c +++ b/src/machine/msp430.c @@ -36,6 +36,7 @@ static machine_spec msp430_machine = { { 2, 2 }, /* int */ { 4, 2 }, /* long */ { 8, 2 }, /* long long */ + { 1, 1 }, /* _Bool */ 1, 2, 2, 2, /* int1/2/4/8 align */ 2, 2, /* wchar_t, size_t size */ TRUE, TRUE, /* char, wchar_t signed */ diff --git a/src/machine/sdcc.c b/src/machine/sdcc.c index daa5cc7..3cfa6ef 100644 --- a/src/machine/sdcc.c +++ b/src/machine/sdcc.c @@ -67,6 +67,7 @@ static machine_spec sdcc_machine = { { 2, 1 }, /* int */ { 4, 1 }, /* long */ { 8, 1 }, /* long long */ + { 1, 1 }, /* _Bool */ 1, 1, 1, 1, /* int1/2/4/8 align */ 2, 2, /* wchar_t, size_t size */ TRUE, TRUE, /* char, wchar_t signed */ diff --git a/src/machine/self.c b/src/machine/self.c index f2cd164..3611304 100644 --- a/src/machine/self.c +++ b/src/machine/self.c @@ -84,6 +84,7 @@ static machine_spec self_machine = { { sizeof(int), __alignof__(int) }, /* int */ { sizeof(long), __alignof__(long) }, /* long */ { sizeof(long long), __alignof__(long long) }, /* long long */ + { sizeof(_Bool), __alignof__(_Bool) }, /* _Bool */ __alignof__(myint1), __alignof__(myint2), __alignof__(myint4), __alignof__(myint8), /* int1/2/4/8 align */ sizeof(wchar_t), sizeof(size_t), /* wchar_t, size_t size */ diff --git a/src/semantics.c b/src/semantics.c index 1f544af..19c4cae 100644 --- a/src/semantics.c +++ b/src/semantics.c @@ -697,6 +697,7 @@ void parse_declarator(type_element modifiers, declarator d, bool bitfield, case RID_CHAR: newtype = char_type; break; case RID_FLOAT: newtype = float_type; break; case RID_DOUBLE: newtype = double_type; break; + case RID_BOOL: newtype = _Bool_type; break; case RID_VOID: newtype = void_type; break; case RID_AUTO: case RID_STATIC: case RID_EXTERN: case RID_REGISTER: case RID_TYPEDEF: case RID_COMMAND: @@ -3614,6 +3615,7 @@ static char *rid_name_int(int id) case RID_UNSIGNED: return "unsigned"; case RID_SHORT: return "short"; case RID_LONG: return "long"; + case RID_BOOL: return "_Bool"; case RID_AUTO: return "auto"; case RID_STATIC: return "static"; case RID_EXTERN: return "extern"; diff --git a/src/types.c b/src/types.c index d79ca53..8431fab 100644 --- a/src/types.c +++ b/src/types.c @@ -80,7 +80,7 @@ struct type tp_short, tp_unsigned_short, tp_int, tp_unsigned_int, tp_long, tp_unsigned_long, - tp_long_long, tp_unsigned_long_long, + tp_long_long, tp_unsigned_long_long, tp_Bool, /* Used as the rep type of enums whose constants are derived from template arguments and whose size is hence unknown. The unknown int type has the highest rank (its unsignedness @@ -192,7 +192,7 @@ type float_type, double_type, long_double_type, int_type, unsigned_int_type, long_type, unsigned_long_type, long_long_type, unsigned_long_long_type, short_type, unsigned_short_type, char_type, char_array_type, wchar_type, wchar_array_type, - unsigned_char_type, signed_char_type, void_type, ptr_void_type, + unsigned_char_type, signed_char_type, _Bool_type, void_type, ptr_void_type, const_ptr_void_type, size_t_type, ptrdiff_t_type, intptr_type, int2_type, uint2_type, int4_type, uint4_type, int8_type, uint8_type, @@ -463,6 +463,7 @@ void init_types(void) signed_char_type = make_primitive(tp_signed_char, 1, target->int1_align); unsigned_char_type = make_primitive(tp_unsigned_char, 1, target->int1_align); char_type = make_primitive(tp_char, 1, target->int1_align); + _Bool_type = make_primitive(tp_Bool, target->t_Bool.size, target->t_Bool.align); int2_type = lookup_primitive(tp_int2, 2, target->int2_align, FALSE); uint2_type = lookup_primitive(tp_uint2, 2, target->int2_align, TRUE); @@ -1530,6 +1531,9 @@ static type_element primitive2ast(region r, location loc, int primitive, break; case tp_signed_char: return rid2ast(r, loc, RID_SIGNED, rid2ast(r, loc, RID_CHAR, rest)); + case tp_Bool: + keyword = RID_BOOL; + break; case tp_unsigned_short: isunsigned = TRUE; case tp_short: diff --git a/src/types.h b/src/types.h index 4928d03..3ee0fed 100644 --- a/src/types.h +++ b/src/types.h @@ -51,7 +51,7 @@ extern type float_type, double_type, long_double_type, int_type, unsigned_int_type, long_type, unsigned_long_type, long_long_type, unsigned_long_long_type, short_type, unsigned_short_type, char_type, char_array_type, wchar_type, wchar_array_type, - unsigned_char_type, signed_char_type, void_type, ptr_void_type, + unsigned_char_type, signed_char_type, _Bool_type, void_type, ptr_void_type, size_t_type, ptrdiff_t_type, intptr_type, unknown_int_type, unknown_number_type, const_ptr_void_type;