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/boolarg/BoolTest.nc b/nregress/c99c11/boolarg/BoolTest.nc new file mode 100644 index 0000000..a7803b7 --- /dev/null +++ b/nregress/c99c11/boolarg/BoolTest.nc @@ -0,0 +1,4 @@ +interface BoolTest { + command void test(const char *test_name, const _Bool arg); + event void testDone(const char *test_name, _Bool result, _Bool arg); +} diff --git a/nregress/c99c11/boolarg/BoolTestM.nc b/nregress/c99c11/boolarg/BoolTestM.nc new file mode 100644 index 0000000..75b3456 --- /dev/null +++ b/nregress/c99c11/boolarg/BoolTestM.nc @@ -0,0 +1,8 @@ +module BoolTestM { + provides interface BoolTest; +} +implementation { + command void BoolTest.test(const char *test_name, const _Bool arg) { + signal BoolTest.testDone(test_name, !arg, arg); + } +} diff --git a/nregress/c99c11/boolarg/TestP.nc b/nregress/c99c11/boolarg/TestP.nc new file mode 100644 index 0000000..b0b5b2a --- /dev/null +++ b/nregress/c99c11/boolarg/TestP.nc @@ -0,0 +1,45 @@ +extern int printf(const char *__restrict format, ...); + +typedef struct { + _Bool a; +} bool_test_args; + +nx_struct nx_header { + nx_uint32_t src; + nx_uint32_t dst; +}; + +module TestP { + uses interface BoolTest; +} +implementation { + int main() @C() @spontaneous() { +#define do_test(test_name, bool_expr) call BoolTest.test(#test_name, bool_expr) + + do_test(TrueConst, 1); + do_test(TrueExpr, 1 == 1 && 0 < 1); + do_test(TrueExprSC, 0 == 0 || 0 > 1); + do_test(IntTrue, 1234); + do_test(FloatTrue, 1.23); + do_test(String, "string"); + + do_test(FalseConst, 0); + do_test(FalseExpr, 0 == 1 || 0 > 1); + do_test(FalseExprSC, 1 == 0 && 0 < 1); + do_test(IntZero, 0); + do_test(FloatZero, 0.0); + do_test(NullVoid, (const void *)0); + do_test(NullULL, (unsigned long long *)0); + do_test(NullStruct, (const bool_test_args *const __restrict)0); + do_test(NullFnP, (int (*)(char[], double))0); + do_test(Network, (nx_uint32_t *)0); + do_test(NetworkStruct, (nx_struct nx_header *)0); +#undef do_test + + return 0; + } + + event void BoolTest.testDone(const char *test_name, _Bool result, _Bool arg) { + printf("%15s: %d -> %d\n", test_name, arg, result); + } +} diff --git a/nregress/c99c11/boolarg/test.nc b/nregress/c99c11/boolarg/test.nc new file mode 100644 index 0000000..b6df3ce --- /dev/null +++ b/nregress/c99c11/boolarg/test.nc @@ -0,0 +1,7 @@ +configuration test { +} +implementation { + components TestP, BoolTestM; + + TestP.BoolTest -> BoolTestM; +} diff --git a/nregress/c99c11/boolgeneric/BoolTest.nc b/nregress/c99c11/boolgeneric/BoolTest.nc new file mode 100644 index 0000000..6b04999 --- /dev/null +++ b/nregress/c99c11/boolgeneric/BoolTest.nc @@ -0,0 +1,11 @@ +typedef struct { + _Bool a:1; + _Bool b; +} bool_test_args; + +interface BoolTest { + command void unary(const _Bool a); + command void binary(const bool_test_args args); + event void unaryDone(const char *test_name, _Bool result, _Bool arg); + event void binaryDone(const char *test_name, _Bool result, bool_test_args args); +} diff --git a/nregress/c99c11/boolgeneric/BoolTestM.nc b/nregress/c99c11/boolgeneric/BoolTestM.nc new file mode 100644 index 0000000..709ae0e --- /dev/null +++ b/nregress/c99c11/boolgeneric/BoolTestM.nc @@ -0,0 +1,15 @@ +generic module BoolTestM(_Bool val, char test_name[]) { + provides interface BoolTest; +} +implementation { + command void BoolTest.unary(const _Bool a) { + const _Bool result = val ? a : !a; + signal BoolTest.unaryDone(test_name, result, a); + } + + command void BoolTest.binary(const bool_test_args args) { + const _Bool xor = args.a ^ args.b; + const _Bool result = val ? xor : !xor; + signal BoolTest.binaryDone(test_name, result, args); + } +} diff --git a/nregress/c99c11/boolgeneric/TestP.nc b/nregress/c99c11/boolgeneric/TestP.nc new file mode 100644 index 0000000..c4e64f6 --- /dev/null +++ b/nregress/c99c11/boolgeneric/TestP.nc @@ -0,0 +1,31 @@ +extern int printf(const char *__restrict format, ...); + +module TestP { + uses interface BoolTest; +} +implementation { + int main() @C() @spontaneous() { + bool_test_args args; + + call BoolTest.unary(0); + call BoolTest.unary(1); + args.a = args.b = 0; + call BoolTest.binary(args); + args.b = 1; + call BoolTest.binary(args); + args.a = 1; args.b = 0; + call BoolTest.binary(args); + args.a = args.b = 1; + call BoolTest.binary(args); + + return 0; + } + + event void BoolTest.unaryDone(const char *test_name, _Bool result, _Bool arg) { + printf("%15s: %d -> %d\n", test_name, arg, result); + } + + event void BoolTest.binaryDone(const char *test_name, _Bool result, bool_test_args args) { + printf("%15s: %d, %d -> %d\n", test_name, args.a, args.b, result); + } +} diff --git a/nregress/c99c11/boolgeneric/test.nc b/nregress/c99c11/boolgeneric/test.nc new file mode 100644 index 0000000..5edc98f --- /dev/null +++ b/nregress/c99c11/boolgeneric/test.nc @@ -0,0 +1,34 @@ +nx_struct nx_header { + nx_uint32_t src; + nx_uint32_t dst; +}; + +configuration test { +} +implementation { + components TestP; +#define define_test(test_name, bool_expr) \ + components new BoolTestM(bool_expr, #test_name) as Test##test_name; \ + Test##test_name <- TestP.BoolTest + + define_test(TrueConst, 1); + define_test(TrueExpr, 1 == 1 && 0 < 1); + define_test(TrueExprSC, 0 == 0 || 0 > 1); + define_test(IntTrue, 1234); + define_test(FloatTrue, 1.23); + define_test(String, "string"); + + define_test(FalseConst, 0); + define_test(FalseExpr, 0 == 1 || 0 > 1); + define_test(FalseExprSC, 1 == 0 && 0 < 1); + define_test(IntZero, 0); + define_test(FloatZero, 0.0); + define_test(NullVoid, (const void *)0); + define_test(NullULL, (unsigned long long *)0); + define_test(NullStruct, (const bool_test_args *const __restrict)0); + define_test(NullFnP, (int (*)(char[], double))0); + define_test(Network, (nx_uint32_t *)0); + define_test(NetworkStruct, (nx_struct nx_header *)0); + +#undef define_test +} diff --git a/nregress/c99c11/boolinit/BoolInit.nc b/nregress/c99c11/boolinit/BoolInit.nc new file mode 100644 index 0000000..08ba541 --- /dev/null +++ b/nregress/c99c11/boolinit/BoolInit.nc @@ -0,0 +1,4 @@ +interface BoolInit { + command void test(); + event void testDone(const char *test_name, _Bool value); +} diff --git a/nregress/c99c11/boolinit/BoolReturn.nc b/nregress/c99c11/boolinit/BoolReturn.nc new file mode 100644 index 0000000..236ed62 --- /dev/null +++ b/nregress/c99c11/boolinit/BoolReturn.nc @@ -0,0 +1,3 @@ +interface BoolReturn { + command _Bool get(); +} diff --git a/nregress/c99c11/boolinit/NegativeIntM.nc b/nregress/c99c11/boolinit/NegativeIntM.nc new file mode 100644 index 0000000..c55cccf --- /dev/null +++ b/nregress/c99c11/boolinit/NegativeIntM.nc @@ -0,0 +1,17 @@ +module NegativeIntM { + provides { + interface BoolInit; + interface BoolReturn; + } +} +implementation { + _Bool value = -9876; + + command void BoolInit.test() { + signal BoolInit.testDone("NegativeInt", value); + } + + command _Bool BoolReturn.get() { + return -9876; + } +} diff --git a/nregress/c99c11/boolinit/NoneZeroFloatM.nc b/nregress/c99c11/boolinit/NoneZeroFloatM.nc new file mode 100644 index 0000000..954807a --- /dev/null +++ b/nregress/c99c11/boolinit/NoneZeroFloatM.nc @@ -0,0 +1,17 @@ +module NoneZeroFloatM { + provides { + interface BoolInit; + interface BoolReturn; + } +} +implementation { + _Bool value = 3.456; + + command void BoolInit.test() { + signal BoolInit.testDone("NonZeroFloat", value); + } + + command _Bool BoolReturn.get() { + return 3.456; + } +} diff --git a/nregress/c99c11/boolinit/NullM.nc b/nregress/c99c11/boolinit/NullM.nc new file mode 100644 index 0000000..3ac2a38 --- /dev/null +++ b/nregress/c99c11/boolinit/NullM.nc @@ -0,0 +1,17 @@ +module NullM { + provides { + interface BoolInit; + interface BoolReturn; + } +} +implementation { + _Bool value = (void *)0; + + command void BoolInit.test() { + signal BoolInit.testDone("Null", value); + } + + command _Bool BoolReturn.get() { + return (void *)0; + } +} diff --git a/nregress/c99c11/boolinit/PositiveIntM.nc b/nregress/c99c11/boolinit/PositiveIntM.nc new file mode 100644 index 0000000..c92e3f5 --- /dev/null +++ b/nregress/c99c11/boolinit/PositiveIntM.nc @@ -0,0 +1,17 @@ +module PositiveIntM { + provides { + interface BoolInit; + interface BoolReturn; + } +} +implementation { + _Bool value = (unsigned int)1234; + + command void BoolInit.test() { + signal BoolInit.testDone("PositiveInt", value); + } + + command _Bool BoolReturn.get() { + return (unsigned int)1234; + } +} diff --git a/nregress/c99c11/boolinit/StringM.nc b/nregress/c99c11/boolinit/StringM.nc new file mode 100644 index 0000000..02f3737 --- /dev/null +++ b/nregress/c99c11/boolinit/StringM.nc @@ -0,0 +1,18 @@ +module StringM { + provides { + interface BoolInit; + interface BoolReturn; + } +} +implementation { + static const char string[] = "string"; + _Bool value = &string; + + command void BoolInit.test() { + signal BoolInit.testDone("String", value); + } + + command _Bool BoolReturn.get() { + return "string"; + } +} diff --git a/nregress/c99c11/boolinit/TestP.nc b/nregress/c99c11/boolinit/TestP.nc new file mode 100644 index 0000000..f4f3c9e --- /dev/null +++ b/nregress/c99c11/boolinit/TestP.nc @@ -0,0 +1,45 @@ +extern int printf(const char *__restrict __format, ...); + +module TestP { + uses { + interface BoolInit; + interface BoolReturn as ZeroInt; + interface BoolReturn as PositiveInt; + interface BoolReturn as NegativeInt; + interface BoolReturn as ZeroFloat; + interface BoolReturn as NoneZeroFloat; + interface BoolReturn as String; + interface BoolReturn as Null; + } +} +implementation { + static void testDone(const char *test_name, _Bool value) { + printf("%15s: %d\n", test_name, value); + } + + int main() @C() @spontaneous() { + printf("===== BoolInit =====\n"); + call BoolInit.test(); + +#define do_test(test_name) \ + testDone(#test_name, call test_name.get()) + + printf("===== BoolReturn =====\n"); + do_test(ZeroInt); + do_test(ZeroFloat); + do_test(Null); + + do_test(PositiveInt); + do_test(NegativeInt); + do_test(NoneZeroFloat); + do_test(String); + +#undef do_test + + return 0; + } + + event void BoolInit.testDone(const char *test_name, _Bool value) { + testDone(test_name, value); + } +} diff --git a/nregress/c99c11/boolinit/ZeroFloatM.nc b/nregress/c99c11/boolinit/ZeroFloatM.nc new file mode 100644 index 0000000..577b0bb --- /dev/null +++ b/nregress/c99c11/boolinit/ZeroFloatM.nc @@ -0,0 +1,17 @@ +module ZeroFloatM { + provides { + interface BoolInit; + interface BoolReturn; + } +} +implementation { + _Bool value = 0.00; + + command void BoolInit.test() { + signal BoolInit.testDone("ZeroFloat", value); + } + + command _Bool BoolReturn.get() { + return 0.00; + } +} diff --git a/nregress/c99c11/boolinit/ZeroIntM.nc b/nregress/c99c11/boolinit/ZeroIntM.nc new file mode 100644 index 0000000..5c079db --- /dev/null +++ b/nregress/c99c11/boolinit/ZeroIntM.nc @@ -0,0 +1,17 @@ +module ZeroIntM { + provides { + interface BoolInit; + interface BoolReturn; + } +} +implementation { + _Bool value = 0; + + command void BoolInit.test() { + signal BoolInit.testDone("ZeroInt", value); + } + + command _Bool BoolReturn.get() { + return 0; + } +} diff --git a/nregress/c99c11/boolinit/test.nc b/nregress/c99c11/boolinit/test.nc new file mode 100644 index 0000000..4dfb271 --- /dev/null +++ b/nregress/c99c11/boolinit/test.nc @@ -0,0 +1,21 @@ +configuration test { +} +implementation { + components TestP; + +#define define_test(test_name) \ + components test_name##M; \ + test_name##M <- TestP.BoolInit; \ + test_name##M <- TestP.test_name + + define_test(ZeroInt); + define_test(ZeroFloat); + define_test(Null); + + define_test(PositiveInt); + define_test(NegativeInt); + define_test(NoneZeroFloat); + define_test(String); + +#undef define_test +} diff --git a/nregress/c99c11/run1 b/nregress/c99c11/run1 index 29709c2..55d372e 100755 --- a/nregress/c99c11/run1 +++ b/nregress/c99c11/run1 @@ -1,12 +1,11 @@ -keep= -if [ -z "$NESC1" ]; then - NESC1=../../../src/nesc1 - keep=1 -fi +[ -z "$NESC1" ] && keep=1 +: ${NESC:=../../..} +: ${TOOLS:=$NESC/tools} +: ${NESC1:=../../../src/nesc1} cd $1 cfile=/tmp/c99c11.$$.c exe=/tmp/c99c11.out.$$ -$NESC1 -fnesc-separator=__ test.nc -o $cfile && \ +$NESC1 -fnesc-separator=__ -I$TOOLS -fnesc-include=deputy_nodeputy -fnesc-include=nesc_nx test.nc -o $cfile && \ gcc -Wall -g -o $exe $cfile && \ $exe ok=$? diff --git a/nregress/ok/c99c11.boolarg.1 b/nregress/ok/c99c11.boolarg.1 new file mode 100644 index 0000000..8ae7644 --- /dev/null +++ b/nregress/ok/c99c11.boolarg.1 @@ -0,0 +1,17 @@ + TrueConst: 1 -> 0 + TrueExpr: 1 -> 0 + TrueExprSC: 1 -> 0 + IntTrue: 1 -> 0 + FloatTrue: 1 -> 0 + String: 1 -> 0 + FalseConst: 0 -> 1 + FalseExpr: 0 -> 1 + FalseExprSC: 0 -> 1 + IntZero: 0 -> 1 + FloatZero: 0 -> 1 + NullVoid: 0 -> 1 + NullULL: 0 -> 1 + NullStruct: 0 -> 1 + NullFnP: 0 -> 1 + Network: 0 -> 1 + NetworkStruct: 0 -> 1 diff --git a/nregress/ok/c99c11.boolarg.2 b/nregress/ok/c99c11.boolarg.2 new file mode 100644 index 0000000..e69de29 diff --git a/nregress/ok/c99c11.boolarg.exit b/nregress/ok/c99c11.boolarg.exit new file mode 100644 index 0000000..573541a --- /dev/null +++ b/nregress/ok/c99c11.boolarg.exit @@ -0,0 +1 @@ +0 diff --git a/nregress/ok/c99c11.boolgeneric.1 b/nregress/ok/c99c11.boolgeneric.1 new file mode 100644 index 0000000..4e48e3e --- /dev/null +++ b/nregress/ok/c99c11.boolgeneric.1 @@ -0,0 +1,102 @@ + TrueConst: 0 -> 0 + TrueExpr: 0 -> 0 + TrueExprSC: 0 -> 0 + IntTrue: 0 -> 0 + FloatTrue: 0 -> 0 + String: 0 -> 0 + FalseConst: 0 -> 1 + FalseExpr: 0 -> 1 + FalseExprSC: 0 -> 1 + IntZero: 0 -> 1 + FloatZero: 0 -> 1 + NullVoid: 0 -> 1 + NullULL: 0 -> 1 + NullStruct: 0 -> 1 + NullFnP: 0 -> 1 + Network: 0 -> 1 + NetworkStruct: 0 -> 1 + TrueConst: 1 -> 1 + TrueExpr: 1 -> 1 + TrueExprSC: 1 -> 1 + IntTrue: 1 -> 1 + FloatTrue: 1 -> 1 + String: 1 -> 1 + FalseConst: 1 -> 0 + FalseExpr: 1 -> 0 + FalseExprSC: 1 -> 0 + IntZero: 1 -> 0 + FloatZero: 1 -> 0 + NullVoid: 1 -> 0 + NullULL: 1 -> 0 + NullStruct: 1 -> 0 + NullFnP: 1 -> 0 + Network: 1 -> 0 + NetworkStruct: 1 -> 0 + TrueConst: 0, 0 -> 0 + TrueExpr: 0, 0 -> 0 + TrueExprSC: 0, 0 -> 0 + IntTrue: 0, 0 -> 0 + FloatTrue: 0, 0 -> 0 + String: 0, 0 -> 0 + FalseConst: 0, 0 -> 1 + FalseExpr: 0, 0 -> 1 + FalseExprSC: 0, 0 -> 1 + IntZero: 0, 0 -> 1 + FloatZero: 0, 0 -> 1 + NullVoid: 0, 0 -> 1 + NullULL: 0, 0 -> 1 + NullStruct: 0, 0 -> 1 + NullFnP: 0, 0 -> 1 + Network: 0, 0 -> 1 + NetworkStruct: 0, 0 -> 1 + TrueConst: 0, 1 -> 1 + TrueExpr: 0, 1 -> 1 + TrueExprSC: 0, 1 -> 1 + IntTrue: 0, 1 -> 1 + FloatTrue: 0, 1 -> 1 + String: 0, 1 -> 1 + FalseConst: 0, 1 -> 0 + FalseExpr: 0, 1 -> 0 + FalseExprSC: 0, 1 -> 0 + IntZero: 0, 1 -> 0 + FloatZero: 0, 1 -> 0 + NullVoid: 0, 1 -> 0 + NullULL: 0, 1 -> 0 + NullStruct: 0, 1 -> 0 + NullFnP: 0, 1 -> 0 + Network: 0, 1 -> 0 + NetworkStruct: 0, 1 -> 0 + TrueConst: 1, 0 -> 1 + TrueExpr: 1, 0 -> 1 + TrueExprSC: 1, 0 -> 1 + IntTrue: 1, 0 -> 1 + FloatTrue: 1, 0 -> 1 + String: 1, 0 -> 1 + FalseConst: 1, 0 -> 0 + FalseExpr: 1, 0 -> 0 + FalseExprSC: 1, 0 -> 0 + IntZero: 1, 0 -> 0 + FloatZero: 1, 0 -> 0 + NullVoid: 1, 0 -> 0 + NullULL: 1, 0 -> 0 + NullStruct: 1, 0 -> 0 + NullFnP: 1, 0 -> 0 + Network: 1, 0 -> 0 + NetworkStruct: 1, 0 -> 0 + TrueConst: 1, 1 -> 0 + TrueExpr: 1, 1 -> 0 + TrueExprSC: 1, 1 -> 0 + IntTrue: 1, 1 -> 0 + FloatTrue: 1, 1 -> 0 + String: 1, 1 -> 0 + FalseConst: 1, 1 -> 1 + FalseExpr: 1, 1 -> 1 + FalseExprSC: 1, 1 -> 1 + IntZero: 1, 1 -> 1 + FloatZero: 1, 1 -> 1 + NullVoid: 1, 1 -> 1 + NullULL: 1, 1 -> 1 + NullStruct: 1, 1 -> 1 + NullFnP: 1, 1 -> 1 + Network: 1, 1 -> 1 + NetworkStruct: 1, 1 -> 1 diff --git a/nregress/ok/c99c11.boolgeneric.2 b/nregress/ok/c99c11.boolgeneric.2 new file mode 100644 index 0000000..e69de29 diff --git a/nregress/ok/c99c11.boolgeneric.exit b/nregress/ok/c99c11.boolgeneric.exit new file mode 100644 index 0000000..573541a --- /dev/null +++ b/nregress/ok/c99c11.boolgeneric.exit @@ -0,0 +1 @@ +0 diff --git a/nregress/ok/c99c11.boolinit.1 b/nregress/ok/c99c11.boolinit.1 new file mode 100644 index 0000000..fc09e80 --- /dev/null +++ b/nregress/ok/c99c11.boolinit.1 @@ -0,0 +1,16 @@ +===== BoolInit ===== + ZeroInt: 0 + ZeroFloat: 0 + Null: 0 + PositiveInt: 1 + NegativeInt: 1 + NonZeroFloat: 1 + String: 1 +===== BoolReturn ===== + ZeroInt: 0 + ZeroFloat: 0 + Null: 0 + PositiveInt: 1 + NegativeInt: 1 + NoneZeroFloat: 1 + String: 1 diff --git a/nregress/ok/c99c11.boolinit.2 b/nregress/ok/c99c11.boolinit.2 new file mode 100644 index 0000000..9cf4c02 --- /dev/null +++ b/nregress/ok/c99c11.boolinit.2 @@ -0,0 +1,3 @@ +StringM.nc:9:1: warning: the address of ‘StringM__string’ will always evaluate as ‘true’ [-Waddress] + _Bool value = &string; + ^ ~~~ diff --git a/nregress/ok/c99c11.boolinit.exit b/nregress/ok/c99c11.boolinit.exit new file mode 100644 index 0000000..573541a --- /dev/null +++ b/nregress/ok/c99c11.boolinit.exit @@ -0,0 +1 @@ +0 diff --git a/nregress/ok/runnable.generic1.exit b/nregress/ok/runnable.generic1.exit index 9902f17..573541a 100644 --- a/nregress/ok/runnable.generic1.exit +++ b/nregress/ok/runnable.generic1.exit @@ -1 +1 @@ -28 +0 diff --git a/src/c-lex.h b/src/c-lex.h index a9a4e72..d502106 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 4faae29..22632d3 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 _Noreturn, SCSPEC, RID_NORETURN asm, ASM_KEYWORD, NORID auto, SCSPEC, RID_AUTO diff --git a/src/cval.c b/src/cval.c index a65a526..5872dec 100644 --- a/src/cval.c +++ b/src/cval.c @@ -154,7 +154,7 @@ cval make_cval_address(data_declaration ddecl, label_declaration ldecl, cval make_cval_address_unknown_offset(cval c) /* Requires: cval_isaddress(c) - Returns: a constant identical to c except that the offset is now unknowjn + Returns: a constant identical to c except that the offset is now unknown */ { assert(cval_isaddress(c)); @@ -393,6 +393,10 @@ cval cval_cast(cval c, type to) default:assert(0); return c; } } + else if (type_Bool(to) && cval_knownbool(c)) + { + return cval_boolvalue(c) ? cval_one : cval_zero; + } else { cval tosize_cval = type_size(to); @@ -1040,9 +1044,8 @@ void cval_print(FILE *f, cval c) { switch (c.kind) { - case cval_float: - case cval_float_complex: - break; + case cval_float: fprintf(f, "%Lf", c.d); break; + case cval_float_complex: fprintf(f, "%Lf %Lf", c.d, c.d_i); break; case cval_uint: fprintf(f, "%llu", c.ui); break; case cval_uint_complex: fprintf(f, "%llu %llu", c.ui, c.ui_i); break; case cval_sint: fprintf(f, "%lld", c.si); break; @@ -1071,6 +1074,7 @@ void cval_debug(cval c) else printf(" - %lld", -c.si); printf(">"); + break; default: printf("[size: %u]", (unsigned)c.isize); cval_print(stdout, c); diff --git a/src/expr.c b/src/expr.c index 7614fcc..844a1d1 100644 --- a/src/expr.c +++ b/src/expr.c @@ -267,7 +267,15 @@ bool check_conversion(type to, type from) if (type_void(to)) return TRUE; - if (type_integer(to)) + if (type_Bool(to)) + { + if (!(type_scalar(from) || type_floating(to) || type_pointer(from))) + { + error("aggregate value used where a _Bool was expected"); + return FALSE; + } + } + else if (type_integer(to)) { if (!type_scalar(from)) { @@ -490,6 +498,10 @@ bool check_assignment(type lhstype, type rhstype, expression rhs, context, fundecl, parmnum); return check_conversion(lhstype, rhstype); } + else if (type_Bool(lhstype) && type_pointer(rhstype)) + { + return check_conversion(lhstype, rhstype); + } else if (type_integral(lhstype) && type_pointer(rhstype)) { warn_for_assignment("%s makes integer from pointer without a cast", 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/nesc-abstract.c b/src/nesc-abstract.c index bd61e72..f123cc8 100644 --- a/src/nesc-abstract.c +++ b/src/nesc-abstract.c @@ -942,6 +942,11 @@ void set_parameter_values(nesc_declaration cdecl, expression args) if (args->type != error_type) error_with_location(l, "component arguments must be constants"); } + else if (type_Bool(vd->ddecl->type)) + { + if (!constant_knownbool(args->cst)) + error_with_location(l, "bool constant expected"); + } else if (type_integer(vd->ddecl->type)) { if (!constant_integral(args->cst)) diff --git a/src/nesc-task.c b/src/nesc-task.c index eb10fdf..03d7827 100644 --- a/src/nesc-task.c +++ b/src/nesc-task.c @@ -217,7 +217,7 @@ void handle_task_declaration(variable_decl vdecl) void load_scheduler(void) { scheduler = load(l_component, toplevel_location, scheduler_name, FALSE); - if (scheduler_name) + if (scheduler) { data_declaration intf = env_lookup(scheduler->env->id_env, scheduler_interface_name, TRUE); diff --git a/src/semantics.c b/src/semantics.c index 161caab..c01d6c5 100644 --- a/src/semantics.c +++ b/src/semantics.c @@ -695,6 +695,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: @@ -3612,6 +3613,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..58bd106 100644 --- a/src/types.c +++ b/src/types.c @@ -61,7 +61,7 @@ struct type - the integral types are ordered by "rank" (see c9x std) and unsignedness (unsigned > signed) (common_primitive_type relies on this order) - - The tp_[u]int types must be before tp_char (for the + - The tp_[u]int types must be before tp_Bool (for the assert in common_primitive_type). These types are only used when the corresponding size is not available amongst short/int/long/long long @@ -75,7 +75,7 @@ struct type tp_int2, tp_uint2, tp_int4, tp_uint4, tp_int8, tp_uint8, - tp_char, + tp_Bool, tp_char, tp_signed_char, tp_unsigned_char, tp_short, tp_unsigned_short, tp_int, tp_unsigned_int, @@ -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, @@ -460,6 +460,7 @@ void init_types(void) unsigned_long_long_type = make_primitive (tp_unsigned_long_long, target->tlong_long.size, target->tlong_long.align); + _Bool_type = make_primitive(tp_Bool, target->t_Bool.size, target->t_Bool.align); 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); @@ -586,6 +587,7 @@ bool type_unsigned(type t) switch (t->u.primitive) { case tp_char: return !flag_signed_char; + case tp_Bool: // see c99 std 6.2.5.6. case tp_unsigned_char: case tp_unsigned_short: case tp_unsigned_int: @@ -689,6 +691,11 @@ bool type_unknown(type t) /* unknown_int or unknown_number */ return type_unknown_int(t) || type_unknown_number(t); } +bool type_Bool(type t) +{ + return t->kind == tk_primitive && t->u.primitive == tp_Bool; +} + bool type_char(type t) { return t->kind == tk_primitive && @@ -945,7 +952,9 @@ bool type_self_promoting(type t) switch (t->u.primitive) { - case tp_float: case tp_char: case tp_unsigned_char: case tp_signed_char: + case tp_float: + case tp_Bool: + case tp_char: case tp_unsigned_char: case tp_signed_char: case tp_short: case tp_unsigned_short: return FALSE; default: @@ -1259,11 +1268,11 @@ static int common_primitive_type(type t1, type t2) /* The pain starts, see 6.3.1.8 of c9x */ /* If the sizes are the same, then we can't have a tp_[u]int or a - tp_char/short/int/long/etc pair (as we only have tp_[u]int if there + tp_Bool/char/short/int/long/etc pair (as we only have tp_[u]int if there is no corresponding integer type of the same size. So we can compare rank by comparing pk1 and pk2 */ - assert(!((pk1 < tp_char && pk2 >= tp_char) || - (pk1 >= tp_char && pk2 < tp_char))); + assert(!((pk1 < tp_Bool && pk2 >= tp_Bool) || + (pk1 >= tp_Bool && pk2 < tp_Bool))); /* the higher rank wins, and if either of the types is unsigned, the result is unsigned (thus unsigned short + int == unsigned int if @@ -1523,6 +1532,9 @@ static type_element primitive2ast(region r, location loc, int primitive, switch (primitive) { + case tp_Bool: + keyword = RID_BOOL; + break; case tp_unsigned_char: isunsigned = TRUE; case tp_char: diff --git a/src/types.h b/src/types.h index 4928d03..efb90eb 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; @@ -175,6 +175,7 @@ bool type_long_double(type t); bool type_unknown_number(type t); bool type_unknown(type t); /* unknown_int or unknown_number */ +void type_print(FILE*, type); bool type_tagged(type t); bool type_integral(type t); /* Does not include enum's */ bool type_floating(type t); @@ -182,6 +183,7 @@ bool type_complex(type t); bool type_float(type t); bool type_double(type t); bool type_void(type t); +bool type_Bool(type t); bool type_char(type t); bool type_function(type t); bool type_array(type t); diff --git a/src/unparse.c b/src/unparse.c index 0bd00c6..3c687a7 100644 --- a/src/unparse.c +++ b/src/unparse.c @@ -311,6 +311,27 @@ static void output_complex(known_cst c) assert(0); } +static bool is_null_constant(known_cst c) +{ + return type_pointer(c->type) && is_zero_constant(c); +} + +static asttype get_constant_type(known_cst c, location l) +{ + declarator d; + type_element qualifiers; + + type2ast(unparse_region, l, c->type, NULL, &d, &qualifiers); + return new_asttype(unparse_region, l, d, qualifiers); +} + +static void output_null_constant(asttype asttype) +{ + output("("); + prt_asttype(asttype); + output(")0"); +} + void output_constant(known_cst c) /* Requires: (constant_integral(c) || constant_float(c)) && type_arithmetic(c->type) @@ -1678,7 +1699,12 @@ void prt_identifier(identifier e, int context_priority) set_location(e->location); if (decl->kind == decl_constant && decl->substitute) - output_constant(decl->value); + { + if (is_null_constant(decl->value)) + output_null_constant(get_constant_type(decl->value, e->location)); + else + output_constant(decl->value); + } else if (decl->kind == decl_error) /* attributes have bad code... */ output_cstring(e->cstring); else