parser: fix sizeof(mod.Type), fix checking sizeof expression (#8065)
							parent
							
								
									dd6febf6fa
								
							
						
					
					
						commit
						ac85257ea0
					
				|  | @ -1022,11 +1022,11 @@ pub mut: | |||
| 
 | ||||
| pub struct SizeOf { | ||||
| pub: | ||||
| 	is_type   bool | ||||
| 	typ       table.Type | ||||
| 	type_name string | ||||
| 	expr      Expr | ||||
| 	pos       token.Position | ||||
| 	is_type bool | ||||
| 	expr    Expr // checker uses this to set typ
 | ||||
| 	pos     token.Position | ||||
| pub mut: | ||||
| 	typ table.Type | ||||
| } | ||||
| 
 | ||||
| pub struct Likely { | ||||
|  |  | |||
|  | @ -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 { | ||||
|  |  | |||
|  | @ -1122,23 +1122,22 @@ pub fn (mut f Fmt) expr(node ast.Expr) { | |||
| 			f.write(node.field_name) | ||||
| 		} | ||||
| 		ast.SizeOf { | ||||
| 			f.write('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) | ||||
| 				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 }
 | ||||
|  |  | |||
|  | @ -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(')') | ||||
| 			} | ||||
| 			node_typ := g.unwrap_generic(node.typ) | ||||
| 			styp := g.typ(node_typ) | ||||
| 			g.write('/*SizeOf*/ sizeof(${util.no_dots(styp)})') | ||||
| 		} | ||||
| 		ast.SqlExpr { | ||||
| 			g.sql_select_expr(node) | ||||
|  |  | |||
|  | @ -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 | ||||
| 				} | ||||
| 			} | ||||
|  |  | |||
|  | @ -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 | ||||
| } | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue