Skip to content

Commit 59384a9

Browse files
committed
Support _Bool as primitive type
1 parent 7ae9c0e commit 59384a9

26 files changed

+202
-10
lines changed

doc/internals-target.txt

+1-1
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ A machine target is specified by filling in a '''machine_spec''' structure, defi
99
* machine_name: name of the target
1010
* 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).
1111
* big_endian: must be true for big-endian targets, false for little-endian ones
12-
* tptr, tfloat, tdouble, tlong_double, tshort, tint, tlong, tlong_long: size and alignment of the corresponding C types.
12+
* tptr, tfloat, tdouble, tlong_double, tshort, tint, tlong, tlong_long, t_Bool: size and alignment of the corresponding C types.
1313
* 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...
1414
* wchar_t_size: size of the wchar_t type
1515
* size_t_size: size of the size_t type (actually this should be the C type, knowing just the size can cause problems)

nregress/c99c11/bool/BoolDone.nc

+6
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
#include "BoolTest.h"
2+
3+
interface BoolDone {
4+
event void unaryDone(bool result, bool arg);
5+
event void binaryDone(bool result, bool_test_args args);
6+
}

nregress/c99c11/bool/BoolDoneM.nc

+16
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
#include <stdio.h>
2+
3+
#include "BoolTest.h"
4+
5+
generic module BoolDoneM(const char testName[]) {
6+
uses interface BoolDone;
7+
}
8+
implementation {
9+
event void BoolDone.unaryDone(bool result, bool arg) {
10+
printf("%10s: %d -> %d\n", testName, arg, result);
11+
}
12+
13+
event void BoolDone.binaryDone(bool result, bool_test_args args) {
14+
printf("%10s: %d, %d -> %d\n", testName, args.a, args.b, result);
15+
}
16+
}

nregress/c99c11/bool/BoolTest.h

+11
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
#ifndef __BOOL_TEST_H__
2+
#define __BOOL_TEST_H__
3+
4+
#include <stdbool.h>
5+
6+
typedef struct {
7+
bool a:1;
8+
bool b;
9+
} bool_test_args;
10+
11+
#endif

nregress/c99c11/bool/BoolTest.nc

+6
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
#include "BoolTest.h"
2+
3+
interface BoolTest {
4+
command void unary(const bool a);
5+
command void binary(const bool_test_args args);
6+
}

nregress/c99c11/bool/BoolTestM.nc

+18
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
#include "BoolTest.h"
2+
3+
generic module BoolTestM(bool val) {
4+
provides interface BoolTest;
5+
provides interface BoolDone;
6+
}
7+
implementation {
8+
command void BoolTest.unary(const bool a) {
9+
const bool result = val ? a : !a;
10+
signal BoolDone.unaryDone(result, a);
11+
}
12+
13+
command void BoolTest.binary(const bool_test_args args) {
14+
const bool result = val ? args.a ^ args.b
15+
: !(args.a ^ args.b);
16+
signal BoolDone.binaryDone(result, args);
17+
}
18+
}

nregress/c99c11/bool/TestP.nc

+25
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
#include <stdio.h>
2+
3+
#include "BoolTest.h"
4+
5+
module TestP {
6+
uses interface BoolTest;
7+
}
8+
implementation {
9+
int main() @C() @spontaneous() {
10+
bool_test_args args;
11+
12+
call BoolTest.unary(false);
13+
call BoolTest.unary(true);
14+
args.a = args.b = false;
15+
call BoolTest.binary(args);
16+
args.b = true;
17+
call BoolTest.binary(args);
18+
args.a = true; args.b = false;
19+
call BoolTest.binary(args);
20+
args.a = args.b = true;
21+
call BoolTest.binary(args);
22+
23+
return 0;
24+
}
25+
}

nregress/c99c11/bool/test.nc

+24
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
#include "BoolTest.h"
2+
3+
#include <stddef.h>
4+
5+
configuration test {
6+
}
7+
implementation {
8+
components TestP;
9+
#define define_test(test_name, bool_expr) \
10+
components new BoolTestM(bool_expr) as Test##test_name; \
11+
components new BoolDoneM(#test_name) as Done##test_name; \
12+
Test##test_name <- TestP.BoolTest; \
13+
Test##test_name <- Done##test_name.BoolDone
14+
15+
define_test(True, 1 == 1 && 0 < 1);
16+
define_test(False, 0 == 1 || 0 > 1);
17+
define_test(Null, NULL);
18+
define_test(IntTrue, 1234);
19+
define_test(IntZero, 0);
20+
define_test(FloatTrue, 1.23);
21+
define_test(FloatZero, 0.0);
22+
23+
#undef define_test
24+
}

nregress/ok/c99c11.bool.1

+42
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
True: 0 -> 0
2+
False: 0 -> 1
3+
Null: 0 -> 1
4+
IntTrue: 0 -> 0
5+
IntZero: 0 -> 1
6+
FloatTrue: 0 -> 0
7+
FloatZero: 0 -> 1
8+
True: 1 -> 1
9+
False: 1 -> 0
10+
Null: 1 -> 0
11+
IntTrue: 1 -> 1
12+
IntZero: 1 -> 0
13+
FloatTrue: 1 -> 1
14+
FloatZero: 1 -> 0
15+
True: 0, 0 -> 0
16+
False: 0, 0 -> 1
17+
Null: 0, 0 -> 1
18+
IntTrue: 0, 0 -> 0
19+
IntZero: 0, 0 -> 1
20+
FloatTrue: 0, 0 -> 0
21+
FloatZero: 0, 0 -> 1
22+
True: 0, 1 -> 1
23+
False: 0, 1 -> 0
24+
Null: 0, 1 -> 0
25+
IntTrue: 0, 1 -> 1
26+
IntZero: 0, 1 -> 0
27+
FloatTrue: 0, 1 -> 1
28+
FloatZero: 0, 1 -> 0
29+
True: 1, 0 -> 1
30+
False: 1, 0 -> 0
31+
Null: 1, 0 -> 0
32+
IntTrue: 1, 0 -> 1
33+
IntZero: 1, 0 -> 0
34+
FloatTrue: 1, 0 -> 1
35+
FloatZero: 1, 0 -> 0
36+
True: 1, 1 -> 0
37+
False: 1, 1 -> 1
38+
Null: 1, 1 -> 1
39+
IntTrue: 1, 1 -> 0
40+
IntZero: 1, 1 -> 1
41+
FloatTrue: 1, 1 -> 0
42+
FloatZero: 1, 1 -> 1

nregress/ok/c99c11.bool.2

+2
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
In component `test':
2+
test.nc:17: warning: passing argument 1 of `TestNull' makes integer from pointer without a cast

nregress/ok/c99c11.bool.exit

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
0

src/c-lex.h

+1
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@ enum rid
5656
RID_LONG,
5757
RID_SIGNED,
5858
RID_COMPLEX,
59+
RID_BOOL,
5960
RID_LASTTYPE,
6061

6162
RID_INLINE = RID_LASTTYPE,

src/c-parse.gperf

+1
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@ __typeof__, TYPEOF, NORID
5050
__volatile, TYPE_QUAL, volatile_qualifier
5151
__volatile__, TYPE_QUAL, volatile_qualifier
5252
__builtin_va_arg, VA_ARG, NORID
53+
_Bool, TYPESPEC, RID_BOOL
5354
_Noreturn, SCSPEC, RID_NORETURN
5455
asm, ASM_KEYWORD, NORID
5556
auto, SCSPEC, RID_AUTO

src/cval.c

+8
Original file line numberDiff line numberDiff line change
@@ -956,6 +956,9 @@ bool uint_inrange(largest_uint x, type t)
956956
if (tsize == sizeof(largest_uint) && type_unsigned(t))
957957
return TRUE;
958958

959+
if (type_Bool(t))
960+
return TRUE;
961+
959962
max = (largest_uint)1 << (BITSPERBYTE * tsize - !type_unsigned(t));
960963

961964
return x < max;
@@ -974,6 +977,9 @@ bool sint_inrange(largest_int x, type t)
974977
if (tsize == sizeof(largest_uint))
975978
return TRUE;
976979

980+
if (type_Bool(t))
981+
return TRUE;
982+
977983
max = (largest_int)1 << (BITSPERBYTE * tsize - !type_unsigned(t));
978984

979985
/* The x<0&&unsigned and largest_int cases have been handled above. */
@@ -984,6 +990,8 @@ bool cval_inrange(cval c, type t)
984990
/* Requires: constant_integral(c)
985991
Returns: TRUE if c is in range of type t. */
986992
{
993+
if (type_Bool(t))
994+
return cval_knownbool(c);
987995
switch (c.kind)
988996
{
989997
case cval_sint: return sint_inrange(c.si, t);

src/machine.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ typedef struct {
1717

1818
size_t word_size;
1919
machine_type_spec tptr, tfloat, tdouble, tlong_double, tshort, tint,
20-
tlong, tlong_long;
20+
tlong, tlong_long, t_Bool;
2121
size_t int1_align, int2_align, int4_align, int8_align;
2222
size_t wchar_t_size, size_t_size;
2323
bool char_signed, wchar_t_signed;

src/machine/avr.c

+1
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ static machine_spec avr_machine = {
3434
{ 2, 1 }, /* int */
3535
{ 4, 1 }, /* long */
3636
{ 8, 1 }, /* long long (unsupported in avr-gcc) */
37+
{ 1, 1 }, /* _Bool */
3738
1, 1, 1, 1, /* int1/2/4/8 align */
3839
2, 2, /* wchar_t, size_t size */
3940
TRUE, TRUE, /* char, wchar_t signed */

src/machine/env_machine.c

+2
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ static machine_spec env_machine = {
4646
{2, 1}, /* int */
4747
{4, 1}, /* long */
4848
{8, 1}, /* long_long */
49+
{1, 1}, /* _Bool */
4950
1, 1, 1, 1, /* int1248_align */
5051
2, 2, /* wchar_size_size */
5152
TRUE, TRUE, /* char_wchar_signed */
@@ -125,6 +126,7 @@ static bool scan_env_machine(machine_spec * machine, const char *envname)
125126
{ "int", &(machine->tint) },
126127
{ "long", &(machine->tlong) },
127128
{ "long_long", &(machine->tlong_long) },
129+
{ "_Bool", &(machine->t_Bool) },
128130
{ NULL, NULL }
129131
};
130132

src/machine/keil.c

+1
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,7 @@ static machine_spec keil_machine = {
9898
{ 2, 1 }, /* int */
9999
{ 4, 1 }, /* long */
100100
{ 8, 1 }, /* long long (unsupported in avr-gcc) */
101+
{ 1, 1 }, /* _Bool */
101102
1, 1, 1, 1, /* int1/2/4/8 align */
102103
2, 2, /* wchar_t, size_t size */
103104
TRUE, TRUE, /* char, wchar_t signed */

src/machine/msp430.c

+1
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ static machine_spec msp430_machine = {
3636
{ 2, 2 }, /* int */
3737
{ 4, 2 }, /* long */
3838
{ 8, 2 }, /* long long */
39+
{ 1, 1 }, /* _Bool */
3940
1, 2, 2, 2, /* int1/2/4/8 align */
4041
2, 2, /* wchar_t, size_t size */
4142
TRUE, TRUE, /* char, wchar_t signed */

src/machine/sdcc.c

+1
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,7 @@ static machine_spec sdcc_machine = {
6767
{ 2, 1 }, /* int */
6868
{ 4, 1 }, /* long */
6969
{ 8, 1 }, /* long long */
70+
{ 1, 1 }, /* _Bool */
7071
1, 1, 1, 1, /* int1/2/4/8 align */
7172
2, 2, /* wchar_t, size_t size */
7273
TRUE, TRUE, /* char, wchar_t signed */

src/machine/self.c

+1
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,7 @@ static machine_spec self_machine = {
8484
{ sizeof(int), __alignof__(int) }, /* int */
8585
{ sizeof(long), __alignof__(long) }, /* long */
8686
{ sizeof(long long), __alignof__(long long) }, /* long long */
87+
{ sizeof(_Bool), __alignof__(_Bool) }, /* _Bool */
8788
__alignof__(myint1), __alignof__(myint2),
8889
__alignof__(myint4), __alignof__(myint8), /* int1/2/4/8 align */
8990
sizeof(wchar_t), sizeof(size_t), /* wchar_t, size_t size */

src/nesc-abstract.c

+5
Original file line numberDiff line numberDiff line change
@@ -942,6 +942,11 @@ void set_parameter_values(nesc_declaration cdecl, expression args)
942942
if (args->type != error_type)
943943
error_with_location(l, "component arguments must be constants");
944944
}
945+
else if (type_Bool(vd->ddecl->type))
946+
{
947+
if (!cval_inrange(args->cst->cval, vd->ddecl->type))
948+
error_with_location(l, "bool constant expected");
949+
}
945950
else if (type_integer(vd->ddecl->type))
946951
{
947952
if (!constant_integral(args->cst))

src/semantics.c

+2
Original file line numberDiff line numberDiff line change
@@ -695,6 +695,7 @@ void parse_declarator(type_element modifiers, declarator d, bool bitfield,
695695
case RID_CHAR: newtype = char_type; break;
696696
case RID_FLOAT: newtype = float_type; break;
697697
case RID_DOUBLE: newtype = double_type; break;
698+
case RID_BOOL: newtype = _Bool_type; break;
698699
case RID_VOID: newtype = void_type; break;
699700
case RID_AUTO: case RID_STATIC: case RID_EXTERN:
700701
case RID_REGISTER: case RID_TYPEDEF: case RID_COMMAND:
@@ -3612,6 +3613,7 @@ static char *rid_name_int(int id)
36123613
case RID_UNSIGNED: return "unsigned";
36133614
case RID_SHORT: return "short";
36143615
case RID_LONG: return "long";
3616+
case RID_BOOL: return "_Bool";
36153617
case RID_AUTO: return "auto";
36163618
case RID_STATIC: return "static";
36173619
case RID_EXTERN: return "extern";

src/types.c

+19-7
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ struct type
6161
- the integral types are ordered by "rank" (see c9x std) and
6262
unsignedness (unsigned > signed) (common_primitive_type
6363
relies on this order)
64-
- The tp_[u]int<n> types must be before tp_char (for the
64+
- The tp_[u]int<n> types must be before tp_Bool (for the
6565
assert in common_primitive_type). These types are only
6666
used when the corresponding size is not available amongst
6767
short/int/long/long long
@@ -75,7 +75,7 @@ struct type
7575

7676
tp_int2, tp_uint2, tp_int4, tp_uint4, tp_int8, tp_uint8,
7777

78-
tp_char,
78+
tp_Bool, tp_char,
7979
tp_signed_char, tp_unsigned_char,
8080
tp_short, tp_unsigned_short,
8181
tp_int, tp_unsigned_int,
@@ -192,7 +192,7 @@ type float_type, double_type, long_double_type,
192192
int_type, unsigned_int_type, long_type, unsigned_long_type,
193193
long_long_type, unsigned_long_long_type, short_type, unsigned_short_type,
194194
char_type, char_array_type, wchar_type, wchar_array_type,
195-
unsigned_char_type, signed_char_type, void_type, ptr_void_type,
195+
unsigned_char_type, signed_char_type, _Bool_type, void_type, ptr_void_type,
196196
const_ptr_void_type,
197197
size_t_type, ptrdiff_t_type, intptr_type,
198198
int2_type, uint2_type, int4_type, uint4_type, int8_type, uint8_type,
@@ -460,6 +460,7 @@ void init_types(void)
460460
unsigned_long_long_type = make_primitive
461461
(tp_unsigned_long_long, target->tlong_long.size, target->tlong_long.align);
462462

463+
_Bool_type = make_primitive(tp_Bool, target->t_Bool.size, target->t_Bool.align);
463464
signed_char_type = make_primitive(tp_signed_char, 1, target->int1_align);
464465
unsigned_char_type = make_primitive(tp_unsigned_char, 1, target->int1_align);
465466
char_type = make_primitive(tp_char, 1, target->int1_align);
@@ -586,6 +587,7 @@ bool type_unsigned(type t)
586587
switch (t->u.primitive)
587588
{
588589
case tp_char: return !flag_signed_char;
590+
case tp_Bool: // see c99 std 6.2.5.6.
589591
case tp_unsigned_char:
590592
case tp_unsigned_short:
591593
case tp_unsigned_int:
@@ -689,6 +691,11 @@ bool type_unknown(type t) /* unknown_int or unknown_number */
689691
return type_unknown_int(t) || type_unknown_number(t);
690692
}
691693

694+
bool type_Bool(type t)
695+
{
696+
return t->kind == tk_primitive && t->u.primitive == tp_Bool;
697+
}
698+
692699
bool type_char(type t)
693700
{
694701
return t->kind == tk_primitive &&
@@ -945,7 +952,9 @@ bool type_self_promoting(type t)
945952

946953
switch (t->u.primitive)
947954
{
948-
case tp_float: case tp_char: case tp_unsigned_char: case tp_signed_char:
955+
case tp_float:
956+
case tp_Bool:
957+
case tp_char: case tp_unsigned_char: case tp_signed_char:
949958
case tp_short: case tp_unsigned_short:
950959
return FALSE;
951960
default:
@@ -1259,11 +1268,11 @@ static int common_primitive_type(type t1, type t2)
12591268

12601269
/* The pain starts, see 6.3.1.8 of c9x */
12611270
/* If the sizes are the same, then we can't have a tp_[u]int<n> or a
1262-
tp_char/short/int/long/etc pair (as we only have tp_[u]int<n> if there
1271+
tp_Bool/char/short/int/long/etc pair (as we only have tp_[u]int<n> if there
12631272
is no corresponding integer type of the same size. So we can compare rank
12641273
by comparing pk1 and pk2 */
1265-
assert(!((pk1 < tp_char && pk2 >= tp_char) ||
1266-
(pk1 >= tp_char && pk2 < tp_char)));
1274+
assert(!((pk1 < tp_Bool && pk2 >= tp_Bool) ||
1275+
(pk1 >= tp_Bool && pk2 < tp_Bool)));
12671276

12681277
/* the higher rank wins, and if either of the types is unsigned, the
12691278
result is unsigned (thus unsigned short + int == unsigned int if
@@ -1523,6 +1532,9 @@ static type_element primitive2ast(region r, location loc, int primitive,
15231532

15241533
switch (primitive)
15251534
{
1535+
case tp_Bool:
1536+
keyword = RID_BOOL;
1537+
break;
15261538
case tp_unsigned_char:
15271539
isunsigned = TRUE;
15281540
case tp_char:

0 commit comments

Comments
 (0)