From 8512c9fc9d5c1ba9f76999c51fa6ce872644ca6a Mon Sep 17 00:00:00 2001 From: Emily Hudson Date: Sat, 21 Dec 2019 21:46:09 +0000 Subject: [PATCH] compiler: __offsetof keyword for C offsetof() macro --- vlib/builtin/cfns.v | 1 - vlib/compiler/cheaders.v | 4 ++++ vlib/compiler/expression.v | 16 ++++++++++++++++ vlib/compiler/token.v | 4 +++- 4 files changed, 23 insertions(+), 2 deletions(-) diff --git a/vlib/builtin/cfns.v b/vlib/builtin/cfns.v index ceccfa720b..9a4a66a9dd 100644 --- a/vlib/builtin/cfns.v +++ b/vlib/builtin/cfns.v @@ -400,4 +400,3 @@ fn C.WaitForSingleObject(voidptr, int) int fn C.ReleaseMutex(voidptr) bool - diff --git a/vlib/compiler/cheaders.v b/vlib/compiler/cheaders.v index a6b6024a74..1c028dc9c4 100644 --- a/vlib/compiler/cheaders.v +++ b/vlib/compiler/cheaders.v @@ -20,6 +20,10 @@ const ( #define TCCSKIP(x) #endif +// for __offset_of +#define __offsetof(s,memb) \\ + ((size_t)((char *)&((s *)0)->memb - (char *)0)) + #define OPTION_CAST(x) (x) ' c_headers = ' diff --git a/vlib/compiler/expression.v b/vlib/compiler/expression.v index c8b5bbc5ec..cafffbc26b 100644 --- a/vlib/compiler/expression.v +++ b/vlib/compiler/expression.v @@ -227,6 +227,7 @@ fn (p mut Parser) name_expr() string { p.string_expr() return 'charptr' } + // known_type := p.table.known_type(name) orig_name := name is_c := name == 'C' && p.peek() == .dot @@ -718,6 +719,21 @@ fn (p mut Parser) factor() string { // p.fgen('$sizeof_typ)') return 'int' } + .key_offsetof { + p.next() + p.check(.lpar) + + offsetof_typ := p.get_type() + p.check(.comma) + + member := p.check_name() + p.check(.rpar) + + p.gen('__offsetof($offsetof_typ, $member)') + + return 'int' + } + .amp, .dot, .mul { // (dot is for enum vals: `.green`) return p.name_expr() diff --git a/vlib/compiler/token.v b/vlib/compiler/token.v index 5e078d4ec2..d1c1f687f2 100644 --- a/vlib/compiler/token.v +++ b/vlib/compiler/token.v @@ -108,6 +108,7 @@ enum TokenKind { key_return key_select key_sizeof + key_offsetof key_struct key_switch key_true @@ -237,11 +238,12 @@ fn build_token_str() []string { s[TokenKind.key_match] = 'match' s[TokenKind.key_select] = 'select' s[TokenKind.key_none] = 'none' + s[TokenKind.key_offsetof] = '__offsetof' return s } const ( - NrTokens = 140 + NrTokens = 141 TokenStr = build_token_str() KEYWORDS = build_keys() )