Skip to content

Commit 8c2b59a

Browse files
committed
factored out some common bitfield code
1 parent c92c355 commit 8c2b59a

3 files changed

Lines changed: 65 additions & 51 deletions

File tree

frontends/c/cgram.y

Lines changed: 1 addition & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -619,7 +619,6 @@ DeclareCMemberVariables(Module *P, AST *astlist, int is_union)
619619
AST *ast;
620620
BitFieldState bitfield = { 0 };
621621
int is_private = -P->defaultPrivate;
622-
AST *last_pos = 0;
623622

624623
if (!astlist) return;
625624
if (astlist->kind != AST_STMTLIST) {
@@ -673,59 +672,12 @@ DeclareCMemberVariables(Module *P, AST *astlist, int is_union)
673672
}
674673
while (idlist) {
675674
ident = idlist->left;
676-
// not in a bitfield
677-
bitfield.max_size = bitfield.offset = 0;
678675
MaybeDeclareMemberVar(P, ident, typ, is_private, NORMAL_VAR, &bitfield);
679676
idlist = idlist->right;
680677
}
681678
} else {
682679
ident = idlist;
683-
if (typ->kind == AST_BITFIELD) {
684-
AST *bfield_ast = typ->right;
685-
AST *bfield_typ = typ->left;
686-
AST *bfield_access;
687-
AST *bfield_list = 0;
688-
int tsize;
689-
int bsize = EvalConstExpr(bfield_ast);
690-
Symbol *sym = FindSymbol(&P->objsyms, GetIdentifierName(ident));
691-
692-
if (sym && sym->kind == SYM_ALIAS) {
693-
goto skip_decl;
694-
}
695-
tsize = TypeSize(bfield_typ) * 8;
696-
if (bitfield.max_size == 0 || bitfield.max_size != tsize || bitfield.offset + bsize > bitfield.max_size) {
697-
// start a new bitfield
698-
bitfield.max_size = tsize;
699-
bitfield.offset = 0;
700-
bitfield.ident = AstTempIdentifier("^_bitfield_");
701-
last_pos = MaybeDeclareMemberVar(P, bitfield.ident, bfield_typ, is_private, HIDDEN_VAR, &bitfield);
702-
}
703-
if (bsize > bitfield.max_size) {
704-
ERROR(bfield_ast, "bitfield size %d is greater than type size %d",
705-
bsize, bitfield.max_size);
706-
bsize = bitfield.max_size;
707-
}
708-
if (bsize < 0) {
709-
bsize = 1;
710-
}
711-
bfield_access = NewAST(AST_RANGE, AstInteger(bitfield.offset + bsize - 1), AstInteger(bitfield.offset));
712-
if (!IsUnsignedType(bfield_typ)) {
713-
bfield_access->d.ival = 1;
714-
}
715-
bfield_access = NewAST(AST_RANGEREF, bitfield.ident, bfield_access);
716-
bfield_access = NewAST(AST_CAST, bfield_typ, bfield_access);
717-
DeclareMemberAlias(P, ident, bfield_access);
718-
bfield_list = NewAST(AST_DECLARE_BITFIELD, bfield_access, ident);
719-
bfield_list = NewAST(AST_LISTHOLDER, bfield_list, NULL);
720-
P->pendingvarblock = ListInsertBefore(P->pendingvarblock, last_pos, bfield_list);
721-
bitfield.offset += bsize;
722-
skip_decl:
723-
;
724-
} else {
725-
// not in a bitfield
726-
bitfield.max_size = bitfield.offset = 0;
727-
MaybeDeclareMemberVar(P, ident, typ, is_private, NORMAL_VAR, &bitfield);
728-
}
680+
MaybeDeclareMemberVar(P, ident, typ, is_private, NORMAL_VAR, &bitfield);
729681
}
730682
}
731683

frontends/common.c

Lines changed: 63 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2276,8 +2276,8 @@ AlreadyDeclared(AST *pendinglist, AST *newIdentifier)
22762276
return NULL;
22772277
}
22782278

2279-
AST *
2280-
MaybeDeclareMemberVar(Module *P, AST *identifier, AST *typ, int is_private, unsigned flags, BitFieldState *bitfield)
2279+
static AST *
2280+
doMaybeDeclareMemberVar(Module *P, AST *identifier, AST *typ, int is_private, unsigned flags, BitFieldState *bitfield)
22812281
{
22822282
AST *ret = 0;
22832283
AST *sub;
@@ -2319,6 +2319,67 @@ MaybeDeclareMemberVar(Module *P, AST *identifier, AST *typ, int is_private, unsi
23192319
return ret;
23202320
}
23212321

2322+
AST *
2323+
MaybeDeclareMemberVar(Module *P, AST *ident, AST *typ, int is_private, unsigned flags, BitFieldState *bitfield)
2324+
{
2325+
AST *ret = NULL;
2326+
if (typ && typ->kind == AST_BITFIELD) {
2327+
AST *bfield_ast = typ->right;
2328+
AST *bfield_typ = typ->left;
2329+
AST *bfield_access;
2330+
AST *bfield_list = 0;
2331+
int tsize;
2332+
int bsize = EvalConstExpr(bfield_ast);
2333+
Symbol *sym = FindSymbol(&P->objsyms, GetIdentifierName(ident));
2334+
2335+
if (!bitfield) {
2336+
ERROR(ident, "Unexpected bitfield declaration");
2337+
return ret;
2338+
}
2339+
if (sym && sym->kind == SYM_ALIAS) {
2340+
goto skip_decl;
2341+
}
2342+
tsize = TypeSize(bfield_typ) * 8;
2343+
if (bitfield->max_size == 0 || bitfield->max_size != tsize || bitfield->offset + bsize > bitfield->max_size) {
2344+
// start a new bitfield
2345+
bitfield->max_size = tsize;
2346+
bitfield->offset = 0;
2347+
bitfield->ident = AstTempIdentifier("^_bitfield_");
2348+
ret = doMaybeDeclareMemberVar(P, bitfield->ident, bfield_typ, is_private, HIDDEN_VAR, NULL);
2349+
bitfield->last_bfield_pos = ret;
2350+
}
2351+
if (bsize > bitfield->max_size) {
2352+
ERROR(bfield_ast, "bitfield size %d is greater than type size %d",
2353+
bsize, bitfield->max_size);
2354+
bsize = bitfield->max_size;
2355+
}
2356+
if (bsize < 0) {
2357+
bsize = 1;
2358+
}
2359+
bfield_access = NewAST(AST_RANGE, AstInteger(bitfield->offset + bsize - 1), AstInteger(bitfield->offset));
2360+
if (!IsUnsignedType(bfield_typ)) {
2361+
bfield_access->d.ival = 1;
2362+
}
2363+
bfield_access = NewAST(AST_RANGEREF, bitfield->ident, bfield_access);
2364+
bfield_access = NewAST(AST_CAST, bfield_typ, bfield_access);
2365+
DeclareMemberAlias(P, ident, bfield_access);
2366+
bfield_list = NewAST(AST_DECLARE_BITFIELD, bfield_access, ident);
2367+
bfield_list = NewAST(AST_LISTHOLDER, bfield_list, NULL);
2368+
P->pendingvarblock = ListInsertBefore(P->pendingvarblock,
2369+
bitfield->last_bfield_pos, bfield_list);
2370+
bitfield->offset += bsize;
2371+
skip_decl:
2372+
;
2373+
} else {
2374+
// not in a bitfield
2375+
if (bitfield) {
2376+
bitfield->max_size = bitfield->offset = 0;
2377+
}
2378+
ret = doMaybeDeclareMemberVar(P, ident, typ, is_private, flags, bitfield);
2379+
}
2380+
return ret;
2381+
}
2382+
23222383
void
23232384
DeclareInterfaceFunctionPointers(Module *P)
23242385
{

frontends/common.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -998,6 +998,7 @@ typedef struct BitFieldState {
998998
AST *ident; /* identifier for bitfield container (usually anonymous) */
999999
int max_size; /* maximum number of bits to hold */
10001000
int offset; /* offset for next bitfield */
1001+
AST *last_bfield_pos; /* last declared bitfield variable */
10011002
} BitFieldState;
10021003

10031004

0 commit comments

Comments
 (0)