Skip to content

Commit ad3e6d4

Browse files
committed
implemented OFFSETOF
1 parent b2560c8 commit ad3e6d4

15 files changed

Lines changed: 73 additions & 4 deletions

File tree

Changelog.txt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
1+
Version 7.6.7
2+
- Add OFFSETOF implementation
3+
14
Version 7.6.6
25
- Increase maximum number of files in a .side from 256 to 1024
36
- Fix Spin2 ABORT (thanks to Ada)

ast.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -894,6 +894,7 @@ static const char *astnames[] = {
894894

895895
"namespace",
896896
"temp_identifier",
897+
"offsetof",
897898
};
898899

899900
//

ast.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -256,6 +256,7 @@ enum astkind {
256256

257257
AST_NAMESPACE = 185,
258258
AST_TEMP_IDENTIFIER = 186,
259+
AST_OFFSETOF = 187,
259260
};
260261

261262
/* forward reference */

backends/cpp/cppexpr.c

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1678,6 +1678,15 @@ PrintExpr(Flexbuf *f, AST *expr, int flags)
16781678
PrintExpr(f, expr->left, flags);
16791679
flexbuf_printf(f, ")");
16801680
break;
1681+
case AST_OFFSETOF:
1682+
{
1683+
AST *typ = ExprType(expr->left);
1684+
const char *fieldname = GetIdentifierName(expr->right);
1685+
flexbuf_printf(f, "offsetof(");
1686+
PrintCastType(f, typ);
1687+
flexbuf_printf(f, ", %s)", fieldname);
1688+
}
1689+
break;
16811690
#if 0
16821691
case AST_VA_START:
16831692
PrintLHS(f, expr->left, flags | PRINTEXPR_ASSIGNMENT);

backends/cpp/outcpp.c

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -832,6 +832,9 @@ PrintCppFile(Flexbuf *f, Module *parse)
832832
if (ModData(parse)->needsString) {
833833
flexbuf_printf(f, "#include <string.h>\n");
834834
}
835+
if (ModData(parse)->needsOffsetof) {
836+
flexbuf_printf(f, "#include <stddef.h>\n");
837+
}
835838
IfdefPropeller(f);
836839
flexbuf_printf(f, "#define __SPIN2CPP__\n");
837840
if (gl_p2) {
@@ -953,6 +956,9 @@ SetCppFlags(CppModData *bedata, AST *ast)
953956
case AST_SPRREF:
954957
bedata->needsCogAccess = 1;
955958
break;
959+
case AST_OFFSETOF:
960+
bedata->needsOffsetof = 1;
961+
break;
956962
case AST_OPERATOR:
957963
{
958964
switch (ast->d.ival) {

backends/cpp/outcpp.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ typedef struct asmmoddata {
3333
char needsLockFuncs;
3434
char needsCogAccess;
3535
char needsCoginit;
36+
char needsOffsetof;
3637

3738
/* flags for whether tuples of size N are needed */
3839
/* if needsTuple & (1<<N) then we need a definition for TupleN__ */

backends/nucode/outnu.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2229,6 +2229,7 @@ static void NuCompileStatement(NuIrList *irl, AST *ast) {
22292229
case AST_MEMREF:
22302230
case AST_CONDRESULT:
22312231
case AST_SIZEOF:
2232+
case AST_OFFSETOF:
22322233
n = NuCompileExpression(irl, ast);
22332234
NuCompileDrop(irl, n);
22342235
break;

expr.c

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1737,6 +1737,35 @@ EvalExpr(AST *expr, unsigned flags, int *valid, int depth)
17371737
}
17381738
return intExpr(TypeSize(typ));
17391739
}
1740+
case AST_OFFSETOF:
1741+
{
1742+
AST *typ = ExprType(expr->left);
1743+
Module *Q;
1744+
Symbol *sym;
1745+
const char *fieldname;
1746+
if (!typ) {
1747+
ERROR(expr, "Unknown type for offsetof");
1748+
return intExpr(0);
1749+
}
1750+
typ = RemoveTypeModifiers(typ);
1751+
if (!IsClassType(typ)) {
1752+
ERROR(expr, "offsetof requires a struct or union type");
1753+
return intExpr(0);
1754+
}
1755+
Q = GetClassPtr(typ);
1756+
if (!Q) {
1757+
ERROR(expr, "Internal error: unable to get class for offsetof");
1758+
return intExpr(0);
1759+
}
1760+
fieldname = GetUserIdentifierName(expr->right);
1761+
sym = LookupSymbolInTable(&Q->objsyms, fieldname);
1762+
if (!sym || sym->kind != SYM_VARIABLE) {
1763+
ERROR(expr, "Unknown field `%s' in offsetof", fieldname);
1764+
return intExpr(0);
1765+
}
1766+
/* For unions all members have offset 0 (already stored in sym->offset) */
1767+
return intExpr(sym->offset);
1768+
}
17401769
case AST_FLOAT:
17411770
if (gl_fixedreal) {
17421771
return fixedExpr(expr->d.ival);
@@ -3411,6 +3440,7 @@ ExprTypeRelative(SymbolTable *table, AST *expr, Module *P)
34113440
case AST_NEW:
34123441
return expr->left;
34133442
case AST_SIZEOF:
3443+
case AST_OFFSETOF:
34143444
return ast_type_unsigned_long;
34153445
case AST_CAST:
34163446
case AST_VA_ARG:

frontends/c/cgram.y

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1134,6 +1134,7 @@ ConstructDefaultValue(AST *decl, AST *val)
11341134
%token C_BUILTIN_COGSTART "__builtin_cogstart"
11351135
%token C_BUILTIN_COGSTART_COG "__builtin_cogstart_cog"
11361136
%token C_BUILTIN_EXPECT "__builtin_expect"
1137+
%token C_BUILTIN_OFFSETOF "__builtin_offsetof"
11371138
%token C_BUILTIN_PRINTF "__builtin_printf"
11381139
%token C_BUILTIN_REV "__builtin_rev"
11391140
%token C_BUILTIN_VA_START "__builtin_va_start"
@@ -1414,7 +1415,9 @@ unary_expression
14141415
| C_SIZEOF '(' type_name ')'
14151416
{ $$ = NewAST(AST_SIZEOF, $3, NULL); }
14161417
| C_SIZEOF unary_expression
1417-
{ $$ = NewAST(AST_SIZEOF, $2, NULL); }
1418+
{ $$ = NewAST(AST_SIZEOF, $2, NULL); }
1419+
| C_BUILTIN_OFFSETOF '(' type_name ',' C_IDENTIFIER ')'
1420+
{ $$ = NewAST(AST_OFFSETOF, $3, $5); }
14181421
;
14191422

14201423
unary_operator

frontends/hloptimize.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -241,6 +241,7 @@ doCheckLocalVar(Symbol *sym, AST *body, VarUse identifierUse, AST **where)
241241
// like memset(foo, 0, sizeof(foo)) work
242242
return doCheckLocalVar(sym, body->left, VAR_SET, where);
243243
case AST_SIZEOF:
244+
case AST_OFFSETOF:
244245
/* these expressions do not actually evaluate their parameters */
245246
return VAR_UNUSED;
246247
case AST_ASSIGN:

0 commit comments

Comments
 (0)