Skip to content

Commit 9204913

Browse files
committed
work on improving union initialization
1 parent c7d3f82 commit 9204913

6 files changed

Lines changed: 28 additions & 11 deletions

File tree

expr.c

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4048,11 +4048,12 @@ AST *FindMethodInList(AST *list, AST *ident, int *curptr)
40484048
/* fix up an initializer list of a given type */
40494049
/* creates an array containing the initializer expressions;
40504050
* each of these may in turn be an array of initializers
4051-
* returns an EXPRLIST containing the items
4051+
* returns an EXPRLIST containing the items; if "unionInit"
4052+
* is true, it adds any explicit method names
40524053
* returns NULL if list is empty
40534054
*/
40544055
AST *
4055-
FixupInitList(AST *type, AST *initval)
4056+
FixupInitList(AST *type, AST *initval, bool unionInit)
40564057
{
40574058
int numelems;
40584059
AST **astarr = 0;
@@ -4163,6 +4164,7 @@ FixupInitList(AST *type, AST *initval)
41634164
curelem = 0;
41644165
while (initval) {
41654166
AST *val = initval;
4167+
AST *methodname = NULL;
41664168
initval = initval->right;
41674169
val->right = NULL;
41684170
if (val->left->kind == AST_INITMODIFIER) {
@@ -4176,7 +4178,8 @@ FixupInitList(AST *type, AST *initval)
41764178
ERROR(fixup, "Internal error, cannot handle nested designators");
41774179
newval = AstInteger(0);
41784180
} else {
4179-
varlist = FindMethodInList(P->finalvarblock, fixup->right, &curelem);
4181+
methodname = fixup->right;
4182+
varlist = FindMethodInList(P->finalvarblock, methodname, &curelem);
41804183
if (!varlist) {
41814184
ERROR(fixup, "%s not found in struct", GetUserIdentifierName(fixup->right));
41824185
break;
@@ -4191,6 +4194,11 @@ FixupInitList(AST *type, AST *initval)
41914194
AST *subtype = ExprType(varlist->left);
41924195
val->left = NewAST(AST_CAST, subtype, val->left);
41934196
}
4197+
if (is_union && unionInit && methodname) {
4198+
if (val->kind == AST_EXPRLIST && val->right == NULL)
4199+
val = val->left;
4200+
val = NewAST(AST_ASSIGN_INIT, methodname, val);
4201+
}
41944202
if (curelem < numelems) {
41954203
astarr[curelem] = val;
41964204
curelem++;

expr.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -190,7 +190,7 @@ AST *BuildExprlistFromObject(AST *expr, AST *typ);
190190

191191
// fix up an initializer list of type "type"
192192
// handles designators like .x = n, and adds any missing 0's
193-
AST *FixupInitList(AST *typ, AST *initval);
193+
AST *FixupInitList(AST *typ, AST *initval, bool unionInit);
194194

195195
/* get a const value as either a constant or a default value */
196196
int32_t const_or_default(Module *M, const char *name, int32_t defaultval);

frontends/c/clang.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
/*
22
* Spin to C/C++ converter
3-
* Copyright 2011-2024 Total Spectrum Software Inc.
3+
* Copyright 2011-2026 Total Spectrum Software Inc. and contributors
44
* See the file COPYING for terms of use
55
*
66
* code for C specific features

frontends/common.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2005,7 +2005,7 @@ DeclareOneGlobalVar(Module *P, AST *ident, AST *type, int inDat)
20052005
return; // just ignore this declaration
20062006
} else {
20072007
if (initializer->kind == AST_EXPRLIST) {
2008-
initializer = FixupInitList(rawtype, initializer);
2008+
initializer = FixupInitList(rawtype, initializer, false);
20092009
*initptr = initializer;
20102010
rawtype->right = AstInteger(AstListLen(initializer));
20112011
} else if (initializer->kind == AST_STRINGPTR) {

functions.c

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -541,7 +541,7 @@ AddInitializers(AST *seq, AST *ident, AST *expr, AST *basetype)
541541
AstReportDone(&saveinfo);
542542
return seq;
543543
} else if (expr->kind == AST_EXPRLIST) {
544-
expr = FixupInitList(basetype, expr);
544+
expr = FixupInitList(basetype, expr, true);
545545
if (IsArrayType(basetype)) {
546546
if (!IsConstExpr(basetype->right)) {
547547
ERROR(ident, "Variable length arrays not supported yet");
@@ -569,13 +569,14 @@ AddInitializers(AST *seq, AST *ident, AST *expr, AST *basetype)
569569
AST *decl;
570570
AST *subident;
571571
AST *curexpr;
572-
while (varlist && varlist->kind == AST_LISTHOLDER) {
572+
bool moreVars = true;
573+
while (varlist && varlist->kind == AST_LISTHOLDER && moreVars) {
573574
decl = varlist->left;
574575
varlist = varlist->right;
575576
if (decl && decl->kind == AST_DECLARE_VAR) {
576577
subtype = decl->left;
577578
decl = decl->right;
578-
while (decl) {
579+
while (decl && moreVars) {
579580
if (decl->kind == AST_LISTHOLDER) {
580581
subident = decl->left;
581582
decl = decl->right;
@@ -594,6 +595,14 @@ AddInitializers(AST *seq, AST *ident, AST *expr, AST *basetype)
594595
} else {
595596
curexpr = AstInteger(0);
596597
}
598+
if (curexpr && curexpr->kind == AST_ASSIGN_INIT) {
599+
subident = curexpr->left;
600+
curexpr = curexpr->right;
601+
if (curexpr && curexpr->kind == AST_CAST) {
602+
subtype = curexpr->left;
603+
}
604+
moreVars = false;
605+
}
597606
sub = NewAST(AST_METHODREF, ident, subident);
598607
seq = AddInitializers(seq, sub, curexpr, subtype);
599608
}
@@ -671,7 +680,7 @@ findLocalsAndDeclare(Function *func, AST *ast)
671680
if (ident->kind == AST_ASSIGN) {
672681
// check for x[] = {a, b, c} type initializers here
673682
if (IsArrayType(basetype) && basetype->right == NULL) {
674-
AST *tmp = FixupInitList(basetype, ident->right);
683+
AST *tmp = FixupInitList(basetype, ident->right, false);
675684
ident->right = tmp;
676685
//fixupInitializer(current, ident->right, basetype);
677686
if (ident->right->kind == AST_EXPRLIST) {

pasm.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1201,7 +1201,7 @@ AssignAddresses(PASMAddresses *addr, SymbolTable *orig_symtab, AST *instrlist, i
12011201
}
12021202
}
12031203
if (initptr && (IsClassType(type) || IsArrayType(type)) ) {
1204-
initializer = FixupInitList(type, initializer);
1204+
initializer = FixupInitList(type, initializer, false);
12051205
*initptr = initializer;
12061206
}
12071207
ALIGNPC(typalign);

0 commit comments

Comments
 (0)