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

@ -1023,10 +1023,10 @@ pub mut:
pub struct SizeOf {
pub:
is_type bool
typ table.Type
type_name string
expr Expr
expr Expr // checker uses this to set typ
pos token.Position
pub mut:
typ table.Type
}
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)
}
ast.SizeOf {
if !node.is_type {
node.typ = c.expr(node.expr)
}
return table.u32_type
}
ast.SqlExpr {

View File

@ -1122,23 +1122,22 @@ pub fn (mut f Fmt) expr(node ast.Expr) {
f.write(node.field_name)
}
ast.SizeOf {
if node.is_type {
f.write('sizeof(')
if node.type_name != '' {
if f.is_external_name(node.type_name) {
f.write(node.type_name)
if node.is_type {
sym := f.table.get_type_symbol(node.typ)
if sym.name != '' {
if f.is_external_name(sym.name) {
f.write(sym.name)
} else {
f.write(f.short_module(node.type_name))
f.write(f.short_module(sym.name))
}
} else {
f.write(f.table.type_to_str(node.typ))
}
f.write(')')
} else {
f.write('sizeof(')
f.expr(node.expr)
f.write(')')
}
f.write(')')
}
ast.SqlExpr {
// 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)
}
ast.SizeOf {
if node.is_type {
node_typ := g.unwrap_generic(node.typ)
mut styp := node.type_name
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(')')
}
styp := g.typ(node_typ)
g.write('/*SizeOf*/ sizeof(${util.no_dots(styp)})')
}
ast.SqlExpr {
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()
p.next() // sizeof
p.check(.lpar)
if !p.tok.can_start_type(table.builtin_type_names) {
if p.tok.kind == .name {
p.mark_var_as_used(p.tok.lit)
}
is_known_var := p.mark_var_as_used(p.tok.lit)
// assume mod. prefix leads to a type
if is_known_var || !(p.known_import(p.tok.lit) || p.tok.kind.is_start_of_type()) {
expr := p.expr(0)
node = ast.SizeOf{
is_type: false
@ -169,6 +168,7 @@ pub fn (mut p Parser) expr(precedence int) ast.Expr {
pos: pos
}
} else {
p.register_used_import(p.tok.lit)
save_expr_mod := p.expr_mod
p.expr_mod = ''
sizeof_type := p.parse_type()
@ -176,7 +176,6 @@ pub fn (mut p Parser) expr(precedence int) ast.Expr {
node = ast.SizeOf{
is_type: true
typ: sizeof_type
type_name: p.table.get_type_symbol(sizeof_type).name
pos: pos
}
}

View File

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