Skip to content

Commit

Permalink
Support _Bool as primitive type
Browse files Browse the repository at this point in the history
  • Loading branch information
tgtakaoka committed Jun 12, 2018
1 parent 7ae9c0e commit 59384a9
Show file tree
Hide file tree
Showing 26 changed files with 202 additions and 10 deletions.
2 changes: 1 addition & 1 deletion doc/internals-target.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
6 changes: 6 additions & 0 deletions nregress/c99c11/bool/BoolDone.nc
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
#include "BoolTest.h"

interface BoolDone {
event void unaryDone(bool result, bool arg);
event void binaryDone(bool result, bool_test_args args);
}
16 changes: 16 additions & 0 deletions nregress/c99c11/bool/BoolDoneM.nc
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
#include <stdio.h>

#include "BoolTest.h"

generic module BoolDoneM(const char testName[]) {
uses interface BoolDone;
}
implementation {
event void BoolDone.unaryDone(bool result, bool arg) {
printf("%10s: %d -> %d\n", testName, arg, result);
}

event void BoolDone.binaryDone(bool result, bool_test_args args) {
printf("%10s: %d, %d -> %d\n", testName, args.a, args.b, result);
}
}
11 changes: 11 additions & 0 deletions nregress/c99c11/bool/BoolTest.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
#ifndef __BOOL_TEST_H__
#define __BOOL_TEST_H__

#include <stdbool.h>

typedef struct {
bool a:1;
bool b;
} bool_test_args;

#endif
6 changes: 6 additions & 0 deletions nregress/c99c11/bool/BoolTest.nc
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
#include "BoolTest.h"

interface BoolTest {
command void unary(const bool a);
command void binary(const bool_test_args args);
}
18 changes: 18 additions & 0 deletions nregress/c99c11/bool/BoolTestM.nc
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
#include "BoolTest.h"

generic module BoolTestM(bool val) {
provides interface BoolTest;
provides interface BoolDone;
}
implementation {
command void BoolTest.unary(const bool a) {
const bool result = val ? a : !a;
signal BoolDone.unaryDone(result, a);
}

command void BoolTest.binary(const bool_test_args args) {
const bool result = val ? args.a ^ args.b
: !(args.a ^ args.b);
signal BoolDone.binaryDone(result, args);
}
}
25 changes: 25 additions & 0 deletions nregress/c99c11/bool/TestP.nc
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
#include <stdio.h>

#include "BoolTest.h"

module TestP {
uses interface BoolTest;
}
implementation {
int main() @C() @spontaneous() {
bool_test_args args;

call BoolTest.unary(false);
call BoolTest.unary(true);
args.a = args.b = false;
call BoolTest.binary(args);
args.b = true;
call BoolTest.binary(args);
args.a = true; args.b = false;
call BoolTest.binary(args);
args.a = args.b = true;
call BoolTest.binary(args);

return 0;
}
}
24 changes: 24 additions & 0 deletions nregress/c99c11/bool/test.nc
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
#include "BoolTest.h"

#include <stddef.h>

configuration test {
}
implementation {
components TestP;
#define define_test(test_name, bool_expr) \
components new BoolTestM(bool_expr) as Test##test_name; \
components new BoolDoneM(#test_name) as Done##test_name; \
Test##test_name <- TestP.BoolTest; \
Test##test_name <- Done##test_name.BoolDone

define_test(True, 1 == 1 && 0 < 1);
define_test(False, 0 == 1 || 0 > 1);
define_test(Null, NULL);
define_test(IntTrue, 1234);
define_test(IntZero, 0);
define_test(FloatTrue, 1.23);
define_test(FloatZero, 0.0);

#undef define_test
}
42 changes: 42 additions & 0 deletions nregress/ok/c99c11.bool.1
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
True: 0 -> 0
False: 0 -> 1
Null: 0 -> 1
IntTrue: 0 -> 0
IntZero: 0 -> 1
FloatTrue: 0 -> 0
FloatZero: 0 -> 1
True: 1 -> 1
False: 1 -> 0
Null: 1 -> 0
IntTrue: 1 -> 1
IntZero: 1 -> 0
FloatTrue: 1 -> 1
FloatZero: 1 -> 0
True: 0, 0 -> 0
False: 0, 0 -> 1
Null: 0, 0 -> 1
IntTrue: 0, 0 -> 0
IntZero: 0, 0 -> 1
FloatTrue: 0, 0 -> 0
FloatZero: 0, 0 -> 1
True: 0, 1 -> 1
False: 0, 1 -> 0
Null: 0, 1 -> 0
IntTrue: 0, 1 -> 1
IntZero: 0, 1 -> 0
FloatTrue: 0, 1 -> 1
FloatZero: 0, 1 -> 0
True: 1, 0 -> 1
False: 1, 0 -> 0
Null: 1, 0 -> 0
IntTrue: 1, 0 -> 1
IntZero: 1, 0 -> 0
FloatTrue: 1, 0 -> 1
FloatZero: 1, 0 -> 0
True: 1, 1 -> 0
False: 1, 1 -> 1
Null: 1, 1 -> 1
IntTrue: 1, 1 -> 0
IntZero: 1, 1 -> 1
FloatTrue: 1, 1 -> 0
FloatZero: 1, 1 -> 1
2 changes: 2 additions & 0 deletions nregress/ok/c99c11.bool.2
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
In component `test':
test.nc:17: warning: passing argument 1 of `TestNull' makes integer from pointer without a cast
1 change: 1 addition & 0 deletions nregress/ok/c99c11.bool.exit
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
0
1 change: 1 addition & 0 deletions src/c-lex.h
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ enum rid
RID_LONG,
RID_SIGNED,
RID_COMPLEX,
RID_BOOL,
RID_LASTTYPE,

RID_INLINE = RID_LASTTYPE,
Expand Down
1 change: 1 addition & 0 deletions src/c-parse.gperf
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
8 changes: 8 additions & 0 deletions src/cval.c
Original file line number Diff line number Diff line change
Expand Up @@ -956,6 +956,9 @@ bool uint_inrange(largest_uint x, type t)
if (tsize == sizeof(largest_uint) && type_unsigned(t))
return TRUE;

if (type_Bool(t))
return TRUE;

max = (largest_uint)1 << (BITSPERBYTE * tsize - !type_unsigned(t));

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

if (type_Bool(t))
return TRUE;

max = (largest_int)1 << (BITSPERBYTE * tsize - !type_unsigned(t));

/* The x<0&&unsigned and largest_int cases have been handled above. */
Expand All @@ -984,6 +990,8 @@ bool cval_inrange(cval c, type t)
/* Requires: constant_integral(c)
Returns: TRUE if c is in range of type t. */
{
if (type_Bool(t))
return cval_knownbool(c);
switch (c.kind)
{
case cval_sint: return sint_inrange(c.si, t);
Expand Down
2 changes: 1 addition & 1 deletion src/machine.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
1 change: 1 addition & 0 deletions src/machine/avr.c
Original file line number Diff line number Diff line change
Expand Up @@ -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 */
Expand Down
2 changes: 2 additions & 0 deletions src/machine/env_machine.c
Original file line number Diff line number Diff line change
Expand Up @@ -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 */
Expand Down Expand Up @@ -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 }
};

Expand Down
1 change: 1 addition & 0 deletions src/machine/keil.c
Original file line number Diff line number Diff line change
Expand Up @@ -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 */
Expand Down
1 change: 1 addition & 0 deletions src/machine/msp430.c
Original file line number Diff line number Diff line change
Expand Up @@ -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 */
Expand Down
1 change: 1 addition & 0 deletions src/machine/sdcc.c
Original file line number Diff line number Diff line change
Expand Up @@ -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 */
Expand Down
1 change: 1 addition & 0 deletions src/machine/self.c
Original file line number Diff line number Diff line change
Expand Up @@ -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 */
Expand Down
5 changes: 5 additions & 0 deletions src/nesc-abstract.c
Original file line number Diff line number Diff line change
Expand Up @@ -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 (!cval_inrange(args->cst->cval, vd->ddecl->type))
error_with_location(l, "bool constant expected");
}
else if (type_integer(vd->ddecl->type))
{
if (!constant_integral(args->cst))
Expand Down
2 changes: 2 additions & 0 deletions src/semantics.c
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down Expand Up @@ -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";
Expand Down
26 changes: 19 additions & 7 deletions src/types.c
Original file line number Diff line number Diff line change
Expand Up @@ -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<n> types must be before tp_char (for the
- The tp_[u]int<n> 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
Expand All @@ -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,
Expand Down Expand Up @@ -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,
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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:
Expand Down Expand Up @@ -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 &&
Expand Down Expand Up @@ -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:
Expand Down Expand Up @@ -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<n> or a
tp_char/short/int/long/etc pair (as we only have tp_[u]int<n> if there
tp_Bool/char/short/int/long/etc pair (as we only have tp_[u]int<n> 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
Expand Down Expand Up @@ -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:
Expand Down
Loading

0 comments on commit 59384a9

Please sign in to comment.