parser: fix sizeof(mod.Type), fix checking sizeof expression (#8065)

pull/8079/head
Nick Treleaven 2021-01-13 05:13:39 +00:00 committed by GitHub
parent dd6febf6fa
commit ac85257ea0
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 33 additions and 44 deletions

View File

@ -1022,11 +1022,11 @@ pub mut:
pub struct SizeOf { pub struct SizeOf {
pub: pub:
is_type bool is_type bool
typ table.Type expr Expr // checker uses this to set typ
type_name string pos token.Position
expr Expr pub mut:
pos token.Position typ table.Type
} }
pub struct Likely { pub struct Likely {

View File

@ -3357,6 +3357,9 @@ pub fn (mut c Checker) expr(node ast.Expr) table.Type {
return c.selector_expr(mut node) return c.selector_expr(mut node)
} }
ast.SizeOf { ast.SizeOf {
if !node.is_type {
node.typ = c.expr(node.expr)
}
return table.u32_type return table.u32_type
} }
ast.SqlExpr { ast.SqlExpr {

View File

@ -1122,23 +1122,22 @@ pub fn (mut f Fmt) expr(node ast.Expr) {
f.write(node.field_name) f.write(node.field_name)
} }
ast.SizeOf { ast.SizeOf {
f.write('sizeof(')
if node.is_type { if node.is_type {
f.write('sizeof(') sym := f.table.get_type_symbol(node.typ)
if node.type_name != '' { if sym.name != '' {
if f.is_external_name(node.type_name) { if f.is_external_name(sym.name) {
f.write(node.type_name) f.write(sym.name)
} else { } else {
f.write(f.short_module(node.type_name)) f.write(f.short_module(sym.name))
} }
} else { } else {
f.write(f.table.type_to_str(node.typ)) f.write(f.table.type_to_str(node.typ))
} }
f.write(')')
} else { } else {
f.write('sizeof(')
f.expr(node.expr) f.expr(node.expr)
f.write(')')
} }
f.write(')')
} }
ast.SqlExpr { ast.SqlExpr {
// sql app.db { select from Contributor where repo == id && user == 0 } // sql app.db { select from Contributor where repo == id && user == 0 }

View File

@ -2719,29 +2719,9 @@ fn (mut g Gen) expr(node ast.Expr) {
g.select_expr(node) g.select_expr(node)
} }
ast.SizeOf { ast.SizeOf {
if node.is_type { node_typ := g.unwrap_generic(node.typ)
node_typ := g.unwrap_generic(node.typ) styp := g.typ(node_typ)
mut styp := node.type_name g.write('/*SizeOf*/ sizeof(${util.no_dots(styp)})')
if styp.starts_with('C.') {
styp = styp[2..]
}
if node.type_name == '' || node.typ.has_flag(.generic) {
styp = g.typ(node_typ)
} else {
sym := g.table.get_type_symbol(node_typ)
if sym.kind == .struct_ {
info := sym.info as table.Struct
if !info.is_typedef {
styp = 'struct ' + styp
}
}
}
g.write('/*SizeOfType*/ sizeof(${util.no_dots(styp)})')
} else {
g.write('/*SizeOfVar*/ sizeof(')
g.expr(node.expr)
g.write(')')
}
} }
ast.SqlExpr { ast.SqlExpr {
g.sql_select_expr(node) g.sql_select_expr(node)

View File

@ -158,10 +158,9 @@ pub fn (mut p Parser) expr(precedence int) ast.Expr {
pos := p.tok.position() pos := p.tok.position()
p.next() // sizeof p.next() // sizeof
p.check(.lpar) p.check(.lpar)
if !p.tok.can_start_type(table.builtin_type_names) { is_known_var := p.mark_var_as_used(p.tok.lit)
if p.tok.kind == .name { // assume mod. prefix leads to a type
p.mark_var_as_used(p.tok.lit) if is_known_var || !(p.known_import(p.tok.lit) || p.tok.kind.is_start_of_type()) {
}
expr := p.expr(0) expr := p.expr(0)
node = ast.SizeOf{ node = ast.SizeOf{
is_type: false is_type: false
@ -169,6 +168,7 @@ pub fn (mut p Parser) expr(precedence int) ast.Expr {
pos: pos pos: pos
} }
} else { } else {
p.register_used_import(p.tok.lit)
save_expr_mod := p.expr_mod save_expr_mod := p.expr_mod
p.expr_mod = '' p.expr_mod = ''
sizeof_type := p.parse_type() sizeof_type := p.parse_type()
@ -176,7 +176,6 @@ pub fn (mut p Parser) expr(precedence int) ast.Expr {
node = ast.SizeOf{ node = ast.SizeOf{
is_type: true is_type: true
typ: sizeof_type typ: sizeof_type
type_name: p.table.get_type_symbol(sizeof_type).name
pos: pos pos: pos
} }
} }

View File

@ -1,7 +1,11 @@
import math import math
import flag
struct S1 { struct S1 {
i voidptr p voidptr
}
struct S2 {
i int
} }
fn test_math_sizeof() { fn test_math_sizeof() {
@ -10,8 +14,12 @@ fn test_math_sizeof() {
} }
fn test_sizeof() { fn test_sizeof() {
// depends on compiler assert sizeof(rune) == 4
assert sizeof(``) in [u32(2), 4] assert sizeof([44]byte) == 44
assert sizeof(``) == 4
// depends on -m32/64 // depends on -m32/64
assert sizeof(S1) in [u32(4), 8] assert sizeof(S1) in [u32(4), 8]
s := S2{}
assert sizeof(s.i) == 4
assert sizeof(flag.Flag) > 4
} }