v4 / vlib / v3 / tests / ssa_build_options_test.v
93 lines · 85 sloc · 2.83 KB · 6c4d26f1f98c5464b012a375667ab345e462f7e0
Raw
1import os
2import v3.flat
3import v3.parser
4import v3.pref
5import v3.ssa
6import v3.types
7
8// parse_checked reads parse checked input for v3 tests.
9fn parse_checked(name string, source string) (&flat.FlatAst, &types.TypeChecker) {
10 src := os.join_path(os.temp_dir(), 'v3_ssa_buildopts_${name}.v')
11 os.write_file(src, source) or { panic(err) }
12 prefs := pref.new_preferences()
13 mut p := parser.Parser.new(prefs)
14 mut a := p.parse_file(src)
15 mut tc := types.TypeChecker.new(a)
16 tc.collect(a)
17 tc.annotate_types()
18 assert tc.errors.len == 0
19 return a, &tc
20}
21
22// func_named converts func named data for v3 tests.
23fn func_named(m &ssa.Module, name string) ssa.Function {
24 for f in m.funcs {
25 if f.name == name {
26 return f
27 }
28 }
29 assert false, 'function ${name} not found'
30 return ssa.Function{}
31}
32
33const prog = 'fn helper() int {\n\treturn 41\n}\n\nfn other() int {\n\treturn 7\n}\n\nfn main() {\n\t_ := helper() + other()\n}\n'
34
35// test_module_name_is_set validates module name is set behavior in v3 tests.
36fn test_module_name_is_set() {
37 a, tc := parse_checked('modname', prog)
38 m := ssa.build_with_used(a, map[string]bool{}, tc)
39 assert m.name == 'main'
40}
41
42// test_default_build_materializes_bodies validates this v3 regression case.
43fn test_default_build_materializes_bodies() {
44 a, tc := parse_checked('default', prog)
45 m := ssa.build_with_used(a, map[string]bool{}, tc)
46 // helper has a real body (blocks) and is not a prototype.
47 helper := func_named(m, 'helper')
48 assert helper.blocks.len > 0
49 assert !helper.is_prototype
50}
51
52// test_skip_fn_bodies_marks_prototypes validates this v3 regression case.
53fn test_skip_fn_bodies_marks_prototypes() {
54 a, tc := parse_checked('skipbodies', prog)
55 m := ssa.build_with_options(a, map[string]bool{}, tc, ssa.BuildOptions{
56 skip_fn_bodies: true
57 })
58 // User functions are registered but bodyless prototypes.
59 helper := func_named(m, 'helper')
60 assert helper.blocks.len == 0
61 assert helper.is_prototype
62 other := func_named(m, 'other')
63 assert other.is_prototype
64}
65
66// test_hot_fn_builds_only_target validates hot fn builds only target behavior in v3 tests.
67fn test_hot_fn_builds_only_target() {
68 a, tc := parse_checked('hotfn', prog)
69 m := ssa.build_with_options(a, map[string]bool{}, tc, ssa.BuildOptions{
70 hot_fn: 'helper'
71 })
72 helper := func_named(m, 'helper')
73 assert helper.blocks.len > 0 // hot target built
74 assert !helper.is_prototype
75 other := func_named(m, 'other')
76 assert other.blocks.len == 0 // non-target stubbed
77 assert other.is_prototype
78}
79
80// test_c_externs_are_external_prototypes validates this v3 regression case.
81fn test_c_externs_are_external_prototypes() {
82 a, tc := parse_checked('externs', prog)
83 m := ssa.build_with_used(a, map[string]bool{}, tc)
84 mut found_extern := false
85 for f in m.funcs {
86 if f.is_c_extern {
87 found_extern = true
88 assert f.is_prototype
89 assert f.linkage == .external
90 }
91 }
92 assert found_extern
93}
94