Skip to content

Commit

Permalink
Issue #1144: Simple version of designated initialisers (#2249)
Browse files Browse the repository at this point in the history
* Issue #1144: Simple version of designated initialisers

* Isssue #1144: Rechecking tests revealed alignment error
  • Loading branch information
suborb committed May 7, 2023
1 parent 57b277b commit 9cd244a
Show file tree
Hide file tree
Showing 3 changed files with 126 additions and 3 deletions.
66 changes: 63 additions & 3 deletions src/sccz80/declinit.c
Expand Up @@ -51,20 +51,25 @@ int initials(const char *dropname, Type *type)
return (desize);
}

static void add_bitfield(Type *bitfield, int *value)
static int add_bitfield(Type *bitfield, int *value)
{
Kind valtype;
double cvalue;

// Early return if we have a designated initialiser
if ( rcmatch('.') ) return 0;

if (constexpr(&cvalue, &valtype, 0)) {
int ival = ((int)cvalue & (( 1 << bitfield->bit_size) - 1)) << bitfield->bit_offset;
check_assign_range(bitfield, cvalue);
*value |= ival;
} else {
errorfmt("Expected a constant value for bitfield assignment", 1);
}
return 1;
}


/*
* initialise structure (also called by init())
*
Expand All @@ -88,10 +93,13 @@ int str_init(Type *tag)
}
if ( i != 0 ) needchar(',');



if ( ptr->offset == last_offset ) {
add_bitfield(ptr, &bitfield_value);
had_bitfield += ptr->bit_size;
continue;
if ( add_bitfield(ptr, &bitfield_value) ) {
continue;
}
} else if ( had_bitfield ) {
sz = ptr->offset;
// We've finished a byte/word of bitfield, we should dump it
Expand All @@ -100,6 +108,57 @@ int str_init(Type *tag)
bitfield_value = 0;
}

if ( rcmatch('.') && isalpha(line[lptr+1]) ) {
char declname[NAMESIZE];
int j, bfsize = ptr->size;
Type *ptr2 = NULL;


// Start of an initialiser
needchar('.');
symname(declname);

for ( j = 0; j < num_fields; j++ ) {
ptr2 = array_get_byindex(tag->fields, j);

if ( strcmp(ptr2->name, declname) == 0 ) {
if ( j < i ) {
errorfmt("Only forward referenced designated specifiers are supported", 1);
} else {
int skip = ptr2->offset - ptr->offset;
// We've found a symbol
needchar('=');

// Storage space
if ( skip > 0 && had_bitfield == 0) {
defstorage(); outdec(skip); nl();
sz += skip;
}
i = j;
ptr = ptr2;
break;
}
} else {
ptr2 = NULL;
}
}
if ( ptr2 == NULL ) {
errorfmt("Unknown structure member %s", 1, declname);
}

if ( ptr->bit_size == 0 ) {
if ( had_bitfield ) {
sz += bfsize;
// We've finished a byte/word of bitfield, we should dump it
outfmt("\t%s\t0x%x\n", had_bitfield <= 8 ? "defb" : "defw", bitfield_value);
had_bitfield = 0;
bitfield_value = 0;
}
}
}



if ( ptr->bit_size ) {
sz = ptr->offset;
last_offset = ptr->offset;
Expand All @@ -108,6 +167,7 @@ int str_init(Type *tag)
continue;
}


last_offset = ptr->offset;

sz += ptr->size == -1 ? 0 : ptr->size;
Expand Down
16 changes: 16 additions & 0 deletions testsuite/Issue_1144_designated_init.c
@@ -0,0 +1,16 @@


struct test {
int x;
int y;
int z:2;
int a:4;
char *str;
};


struct test data = { .z = 1, .str = "hello" };
struct test data1 = { .x = 10, .z=1, .a=4, .str = "hello" };
struct test data2 = { .x = 12, .str = "hello" };


47 changes: 47 additions & 0 deletions testsuite/results/Issue_1144_designated_init.opt
@@ -0,0 +1,47 @@





INCLUDE "z80_crt0.hdr"


SECTION data_compiler
._data
defs 4
defb 0x1
defw i_1+0
SECTION code_compiler
SECTION data_compiler
._data1
defw 10
defs 2
defb 0x11
defw i_1+0
SECTION code_compiler
SECTION data_compiler
._data2
defw 12
defs 3
defw i_1+0
SECTION code_compiler

SECTION rodata_compiler
.i_1
defm "hello"
defb 0



SECTION bss_compiler
SECTION code_compiler



GLOBAL _data
GLOBAL _data1
GLOBAL _data2




0 comments on commit 9cd244a

Please sign in to comment.