mirror of
https://github.com/vlang/v.git
synced 2025-09-24 04:48:28 -04:00
parent
a2b4f08436
commit
1000ada582
@ -403,6 +403,7 @@ pub:
|
||||
name string
|
||||
is_pub bool
|
||||
is_markused bool // an explicit `@[markused]` tag; the const will NOT be removed by `-skip-unused`, no matter what
|
||||
is_exported bool // an explicit `@[export]` tag; the const will NOT be removed by `-skip-unused`, no matter what
|
||||
pos token.Pos
|
||||
attrs []Attr // same value as `attrs` of the ConstDecl to which it belongs
|
||||
is_virtual_c bool // `const C.MY_CONST u8`
|
||||
|
@ -19,7 +19,7 @@ fn (mut g Gen) expr_with_opt_or_block(expr ast.Expr, expr_typ ast.Type, var_expr
|
||||
}
|
||||
g.writeln(';')
|
||||
expr_var := if expr is ast.Ident && expr.kind == .constant {
|
||||
g.get_const_name(expr)
|
||||
g.c_const_name(expr.name)
|
||||
} else if expr is ast.Ident && expr.is_auto_heap() {
|
||||
'(*${expr.name})'
|
||||
} else {
|
||||
|
@ -5260,19 +5260,6 @@ fn (mut g Gen) select_expr(node ast.SelectExpr) {
|
||||
}
|
||||
}
|
||||
|
||||
fn (mut g Gen) get_const_name(node ast.Ident) string {
|
||||
if g.pref.translated && !g.is_builtin_mod
|
||||
&& !util.module_is_builtin(node.name.all_before_last('.')) {
|
||||
mut x := util.no_dots(node.name)
|
||||
if x.starts_with('main__') {
|
||||
x = x['main__'.len..]
|
||||
}
|
||||
return x
|
||||
} else {
|
||||
return '_const_' + g.get_ternary_name(c_name(node.name))
|
||||
}
|
||||
}
|
||||
|
||||
fn (mut g Gen) ident(node ast.Ident) {
|
||||
prevent_sum_type_unwrapping_once := g.prevent_sum_type_unwrapping_once
|
||||
g.prevent_sum_type_unwrapping_once = false
|
||||
@ -5294,28 +5281,16 @@ fn (mut g Gen) ident(node ast.Ident) {
|
||||
}
|
||||
}
|
||||
if node.kind == .constant {
|
||||
if g.pref.translated && !g.is_builtin_mod
|
||||
&& !util.module_is_builtin(node.name.all_before_last('.')) {
|
||||
// Don't prepend "_const" to translated C consts,
|
||||
// but only in user code, continue prepending "_const" to builtin consts.
|
||||
mut x := util.no_dots(node.name)
|
||||
if x.starts_with('main__') {
|
||||
x = x['main__'.len..]
|
||||
}
|
||||
g.write(x)
|
||||
return
|
||||
} else {
|
||||
if g.inside_opt_or_res && node.or_expr.kind != .absent && node.obj.typ.has_flag(.option) {
|
||||
styp := g.base_type(node.obj.typ)
|
||||
g.write('(*(${styp}*)')
|
||||
if g.inside_opt_or_res && node.or_expr.kind != .absent && node.obj.typ.has_flag(.option) {
|
||||
styp := g.base_type(node.obj.typ)
|
||||
g.write('(*(${styp}*)')
|
||||
|
||||
defer {
|
||||
g.write('.data)')
|
||||
}
|
||||
defer {
|
||||
g.write('.data)')
|
||||
}
|
||||
// TODO: globals hack
|
||||
g.write('_const_')
|
||||
}
|
||||
g.write(g.c_const_name(node.name))
|
||||
return
|
||||
}
|
||||
mut is_auto_heap := node.is_auto_heap()
|
||||
mut is_option := false
|
||||
|
@ -33,18 +33,7 @@ fn (mut g Gen) const_decl(node ast.ConstDecl) {
|
||||
}
|
||||
}
|
||||
name := c_name(field.name)
|
||||
mut const_name := '_const_' + name
|
||||
if g.pref.translated && !g.is_builtin_mod
|
||||
&& !util.module_is_builtin(field.name.all_before_last('.')) {
|
||||
if name.starts_with('main__') {
|
||||
const_name = name.all_after_first('main__')
|
||||
}
|
||||
}
|
||||
if !g.is_builtin_mod {
|
||||
if cattr := node.attrs.find_first('export') {
|
||||
const_name = cattr.arg
|
||||
}
|
||||
}
|
||||
const_name := g.c_const_name(field.name)
|
||||
field_expr := field.expr
|
||||
match field.expr {
|
||||
ast.ArrayInit {
|
||||
@ -63,10 +52,11 @@ fn (mut g Gen) const_decl(node ast.ConstDecl) {
|
||||
} else if field.expr.is_fixed && !field.expr.has_index
|
||||
&& ((g.is_cc_msvc && field.expr.elem_type == ast.string_type)
|
||||
|| !elems_are_const) {
|
||||
g.const_decl_init_later_msvc_string_fixed_array(field.mod, name, field.expr,
|
||||
field.typ)
|
||||
g.const_decl_init_later_msvc_string_fixed_array(field.mod, name, const_name,
|
||||
field.expr, field.typ)
|
||||
} else {
|
||||
g.const_decl_init_later(field.mod, name, field.expr, field.typ, false)
|
||||
g.const_decl_init_later(field.mod, name, const_name, field.expr, field.typ,
|
||||
false)
|
||||
}
|
||||
}
|
||||
ast.StringLiteral {
|
||||
@ -85,10 +75,12 @@ fn (mut g Gen) const_decl(node ast.ConstDecl) {
|
||||
old_inside_const_opt_or_res := g.inside_const_opt_or_res
|
||||
g.inside_const_opt_or_res = true
|
||||
unwrap_opt_res := field.expr.or_block.kind != .absent
|
||||
g.const_decl_init_later(field.mod, name, field.expr, field.typ, unwrap_opt_res)
|
||||
g.const_decl_init_later(field.mod, name, const_name, field.expr, field.typ,
|
||||
unwrap_opt_res)
|
||||
g.inside_const_opt_or_res = old_inside_const_opt_or_res
|
||||
} else {
|
||||
g.const_decl_init_later(field.mod, name, field.expr, field.typ, false)
|
||||
g.const_decl_init_later(field.mod, name, const_name, field.expr, field.typ,
|
||||
false)
|
||||
}
|
||||
}
|
||||
else {
|
||||
@ -105,8 +97,8 @@ fn (mut g Gen) const_decl(node ast.ConstDecl) {
|
||||
use_cache_mode := g.pref.build_mode == .build_module || g.pref.use_cache
|
||||
if !use_cache_mode {
|
||||
if ct_value := field.comptime_expr_value() {
|
||||
if g.const_decl_precomputed(field.mod, name, field.name, ct_value,
|
||||
field.typ)
|
||||
if g.const_decl_precomputed(field.mod, name, const_name, field.name,
|
||||
ct_value, field.typ)
|
||||
{
|
||||
continue
|
||||
}
|
||||
@ -115,7 +107,7 @@ fn (mut g Gen) const_decl(node ast.ConstDecl) {
|
||||
if field.is_simple_define_const() {
|
||||
// "Simple" expressions are not going to need multiple statements,
|
||||
// only the ones which are inited later, so it's safe to use expr_string
|
||||
g.const_decl_simple_define(field.mod, field.name, g.expr_string(field_expr))
|
||||
g.const_decl_simple_define(field.mod, field.name, const_name, g.expr_string(field_expr))
|
||||
} else if field.expr is ast.CastExpr {
|
||||
if field.expr.expr is ast.ArrayInit {
|
||||
if field.expr.expr.is_fixed && g.pref.build_mode != .build_module {
|
||||
@ -131,7 +123,8 @@ fn (mut g Gen) const_decl(node ast.ConstDecl) {
|
||||
}
|
||||
should_surround := field.expr.expr is ast.CallExpr
|
||||
&& field.expr.expr.or_block.kind != .absent
|
||||
g.const_decl_init_later(field.mod, name, field.expr, field.typ, should_surround)
|
||||
g.const_decl_init_later(field.mod, name, const_name, field.expr, field.typ,
|
||||
should_surround)
|
||||
} else if field.expr is ast.InfixExpr {
|
||||
mut has_unwrap_opt_res := false
|
||||
if field.expr.left is ast.CallExpr {
|
||||
@ -139,19 +132,20 @@ fn (mut g Gen) const_decl(node ast.ConstDecl) {
|
||||
} else if field.expr.right is ast.CallExpr {
|
||||
has_unwrap_opt_res = field.expr.right.or_block.kind != .absent
|
||||
}
|
||||
g.const_decl_init_later(field.mod, name, field.expr, field.typ, has_unwrap_opt_res)
|
||||
g.const_decl_init_later(field.mod, name, const_name, field.expr, field.typ,
|
||||
has_unwrap_opt_res)
|
||||
} else {
|
||||
g.const_decl_init_later(field.mod, name, field.expr, field.typ, true)
|
||||
g.const_decl_init_later(field.mod, name, const_name, field.expr, field.typ,
|
||||
true)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn (mut g Gen) const_decl_precomputed(mod string, name string, field_name string, ct_value ast.ComptTimeConstValue,
|
||||
fn (mut g Gen) const_decl_precomputed(mod string, name string, cname string, field_name string, ct_value ast.ComptTimeConstValue,
|
||||
typ ast.Type) bool {
|
||||
mut styp := g.styp(typ)
|
||||
cname := if g.pref.translated && !g.is_builtin_mod { name } else { '_const_${name}' }
|
||||
$if trace_const_precomputed ? {
|
||||
eprintln('> styp: ${styp} | cname: ${cname} | ct_value: ${ct_value} | ${ct_value.type_name()}')
|
||||
}
|
||||
@ -179,7 +173,7 @@ fn (mut g Gen) const_decl_precomputed(mod string, name string, field_name string
|
||||
// with -cstrict. Add checker errors for overflows instead,
|
||||
// so V can catch them earlier, instead of relying on the
|
||||
// C compiler for that.
|
||||
g.const_decl_simple_define(mod, name, ct_value.str())
|
||||
g.const_decl_simple_define(mod, name, cname, ct_value.str())
|
||||
return true
|
||||
}
|
||||
if typ == ast.u64_type {
|
||||
@ -274,48 +268,52 @@ fn (mut g Gen) const_decl_write_precomputed(mod string, styp string, cname strin
|
||||
}
|
||||
}
|
||||
|
||||
fn (mut g Gen) const_decl_simple_define(mod string, name string, val string) {
|
||||
fn (mut g Gen) const_decl_simple_define(mod string, name string, cname string, val string) {
|
||||
// Simple expressions should use a #define
|
||||
// so that we don't pollute the binary with unnecessary global vars
|
||||
// Do not do this when building a module, otherwise the consts
|
||||
// will not be accessible.
|
||||
mut x := util.no_dots(name)
|
||||
if g.pref.translated && !g.is_builtin_mod && !util.module_is_builtin(name.all_before_last('.')) {
|
||||
// Don't prepend "_const" to translated C consts,
|
||||
// but only in user code, continue prepending "_const" to builtin consts.
|
||||
if x.starts_with('main__') {
|
||||
x = x['main__'.len..]
|
||||
}
|
||||
} else {
|
||||
x = '_const_${x}'
|
||||
}
|
||||
if g.pref.translated {
|
||||
g.global_const_defs[util.no_dots(name)] = GlobalConstDef{
|
||||
mod: mod
|
||||
def: 'const ${ast.int_type_name} ${x} = ${val};'
|
||||
def: 'const ${ast.int_type_name} ${cname} = ${val};'
|
||||
order: -1
|
||||
}
|
||||
} else {
|
||||
g.global_const_defs[util.no_dots(name)] = GlobalConstDef{
|
||||
mod: mod
|
||||
def: '#define ${x} ${val}'
|
||||
def: '#define ${cname} ${val}'
|
||||
order: -1
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn (mut g Gen) c_const_name(name string) string {
|
||||
return if g.pref.translated && !g.is_builtin_mod { name } else { '_const_${name}' }
|
||||
if name in g.table.export_names {
|
||||
// `@[export] name
|
||||
return g.table.export_names[name]
|
||||
}
|
||||
mut const_name := util.no_dots(name)
|
||||
if g.pref.translated && !g.is_builtin_mod && !util.module_is_builtin(name.all_before_last('.')) {
|
||||
if name.starts_with('main.') {
|
||||
const_name = util.no_dots(name.all_after_first('main.'))
|
||||
}
|
||||
}
|
||||
|
||||
return if g.pref.translated && !g.is_builtin_mod {
|
||||
const_name
|
||||
} else {
|
||||
'_const_' + g.get_ternary_name(c_name(name))
|
||||
}
|
||||
}
|
||||
|
||||
fn (mut g Gen) const_decl_init_later(mod string, name string, expr ast.Expr, typ ast.Type, surround_cbr bool) {
|
||||
fn (mut g Gen) const_decl_init_later(mod string, name string, cname string, expr ast.Expr, typ ast.Type, surround_cbr bool) {
|
||||
if name.starts_with('C__') {
|
||||
return
|
||||
}
|
||||
// Initialize more complex consts in `void _vinit/2{}`
|
||||
// (C doesn't allow init expressions that can't be resolved at compile time).
|
||||
mut styp := g.styp(typ)
|
||||
cname := g.c_const_name(name)
|
||||
mut init := strings.new_builder(100)
|
||||
|
||||
if surround_cbr {
|
||||
@ -372,10 +370,9 @@ fn (mut g Gen) const_decl_init_later(mod string, name string, expr ast.Expr, typ
|
||||
}
|
||||
}
|
||||
|
||||
fn (mut g Gen) const_decl_init_later_msvc_string_fixed_array(mod string, name string, expr ast.ArrayInit,
|
||||
fn (mut g Gen) const_decl_init_later_msvc_string_fixed_array(mod string, name string, cname string, expr ast.ArrayInit,
|
||||
typ ast.Type) {
|
||||
mut styp := g.styp(typ)
|
||||
cname := g.c_const_name(name)
|
||||
mut init := strings.new_builder(100)
|
||||
for i, elem_expr in expr.exprs {
|
||||
if elem_expr is ast.ArrayInit && elem_expr.is_fixed {
|
||||
|
@ -2056,7 +2056,7 @@ fn (mut g Gen) fn_call(node ast.CallExpr) {
|
||||
}
|
||||
}
|
||||
if node.is_fn_a_const {
|
||||
name = g.c_const_name(node.const_name.replace('.', '__'))
|
||||
name = g.c_const_name(node.const_name)
|
||||
}
|
||||
// TODO2
|
||||
// cgen shouldn't modify ast nodes, this should be moved
|
||||
|
@ -203,7 +203,7 @@ pub fn (mut w Walker) mark_root_fns(all_fn_root_names []string) {
|
||||
|
||||
pub fn (mut w Walker) mark_markused_consts() {
|
||||
for ckey, mut constfield in w.all_consts {
|
||||
if constfield.is_markused {
|
||||
if constfield.is_markused || constfield.is_exported {
|
||||
$if trace_skip_unused_markused_consts ? {
|
||||
println('>>>> walking markused const: ${ckey}')
|
||||
}
|
||||
|
@ -2446,9 +2446,11 @@ fn (mut p Parser) const_decl() ast.ConstDecl {
|
||||
p.attrs = []
|
||||
}
|
||||
mut is_markused := false
|
||||
mut is_exported := false
|
||||
for ga in attrs {
|
||||
match ga.name {
|
||||
'markused' { is_markused = true }
|
||||
'export' { is_exported = true }
|
||||
else {}
|
||||
}
|
||||
}
|
||||
@ -2538,6 +2540,7 @@ fn (mut p Parser) const_decl() ast.ConstDecl {
|
||||
comments: comments
|
||||
end_comments: end_comments
|
||||
is_markused: is_markused
|
||||
is_exported: is_exported
|
||||
is_virtual_c: is_virtual_c_const
|
||||
}
|
||||
if is_virtual_c_const {
|
||||
|
Loading…
x
Reference in New Issue
Block a user