mirror of
https://github.com/vlang/v.git
synced 2025-09-13 14:32:26 +03:00
cgen: fix hash stmt code generation (fix #25184) (#25207)
Some checks are pending
Graphics CI / gg-regressions (push) Waiting to run
vlib modules CI / build-module-docs (push) Waiting to run
native backend CI / native-backend-ubuntu (push) Waiting to run
native backend CI / native-backend-windows (push) Waiting to run
Shy and PV CI / v-compiles-puzzle-vibes (push) Waiting to run
Sanitized CI / sanitize-undefined-clang (push) Waiting to run
Sanitized CI / sanitize-undefined-gcc (push) Waiting to run
Sanitized CI / tests-sanitize-address-clang (push) Waiting to run
Sanitized CI / sanitize-address-msvc (push) Waiting to run
Sanitized CI / sanitize-address-gcc (push) Waiting to run
Sanitized CI / sanitize-memory-clang (push) Waiting to run
sdl CI / v-compiles-sdl-examples (push) Waiting to run
Time CI / time-linux (push) Waiting to run
Time CI / time-macos (push) Waiting to run
Time CI / time-windows (push) Waiting to run
toml CI / toml-module-pass-external-test-suites (push) Waiting to run
Tools CI / tools-linux (clang) (push) Waiting to run
Tools CI / tools-linux (gcc) (push) Waiting to run
Tools CI / tools-linux (tcc) (push) Waiting to run
Tools CI / tools-macos (clang) (push) Waiting to run
Tools CI / tools-windows (gcc) (push) Waiting to run
Tools CI / tools-windows (msvc) (push) Waiting to run
Tools CI / tools-windows (tcc) (push) Waiting to run
Tools CI / tools-docker-ubuntu-musl (push) Waiting to run
vab CI / vab-compiles-v-examples (push) Waiting to run
vab CI / v-compiles-os-android (push) Waiting to run
wasm backend CI / wasm-backend (ubuntu-22.04) (push) Waiting to run
wasm backend CI / wasm-backend (windows-2022) (push) Waiting to run
Some checks are pending
Graphics CI / gg-regressions (push) Waiting to run
vlib modules CI / build-module-docs (push) Waiting to run
native backend CI / native-backend-ubuntu (push) Waiting to run
native backend CI / native-backend-windows (push) Waiting to run
Shy and PV CI / v-compiles-puzzle-vibes (push) Waiting to run
Sanitized CI / sanitize-undefined-clang (push) Waiting to run
Sanitized CI / sanitize-undefined-gcc (push) Waiting to run
Sanitized CI / tests-sanitize-address-clang (push) Waiting to run
Sanitized CI / sanitize-address-msvc (push) Waiting to run
Sanitized CI / sanitize-address-gcc (push) Waiting to run
Sanitized CI / sanitize-memory-clang (push) Waiting to run
sdl CI / v-compiles-sdl-examples (push) Waiting to run
Time CI / time-linux (push) Waiting to run
Time CI / time-macos (push) Waiting to run
Time CI / time-windows (push) Waiting to run
toml CI / toml-module-pass-external-test-suites (push) Waiting to run
Tools CI / tools-linux (clang) (push) Waiting to run
Tools CI / tools-linux (gcc) (push) Waiting to run
Tools CI / tools-linux (tcc) (push) Waiting to run
Tools CI / tools-macos (clang) (push) Waiting to run
Tools CI / tools-windows (gcc) (push) Waiting to run
Tools CI / tools-windows (msvc) (push) Waiting to run
Tools CI / tools-windows (tcc) (push) Waiting to run
Tools CI / tools-docker-ubuntu-musl (push) Waiting to run
vab CI / vab-compiles-v-examples (push) Waiting to run
vab CI / v-compiles-os-android (push) Waiting to run
wasm backend CI / wasm-backend (ubuntu-22.04) (push) Waiting to run
wasm backend CI / wasm-backend (windows-2022) (push) Waiting to run
This commit is contained in:
parent
d31aaecc42
commit
487feb9b0e
5 changed files with 282 additions and 99 deletions
|
@ -117,6 +117,8 @@ pub type Stmt = AsmStmt
|
||||||
| StructDecl
|
| StructDecl
|
||||||
| TypeDecl
|
| TypeDecl
|
||||||
|
|
||||||
|
pub type HashStmtNode = IfExpr | HashStmt
|
||||||
|
|
||||||
pub struct EmptyScopeObject {
|
pub struct EmptyScopeObject {
|
||||||
pub mut:
|
pub mut:
|
||||||
name string
|
name string
|
||||||
|
|
|
@ -274,6 +274,11 @@ mut:
|
||||||
export_funcs []string // for .dll export function names
|
export_funcs []string // for .dll export function names
|
||||||
//
|
//
|
||||||
type_default_impl_level int
|
type_default_impl_level int
|
||||||
|
preinclude_nodes []&ast.HashStmtNode // allows hash stmts to go before `includes`
|
||||||
|
include_nodes []&ast.HashStmtNode // all hash stmts to go `includes`
|
||||||
|
definition_nodes []&ast.HashStmtNode // allows hash stmts to go `definitions`
|
||||||
|
postinclude_nodes []&ast.HashStmtNode // allows hash stmts to go after all the rest of the code generation
|
||||||
|
curr_comptime_node &ast.Expr = unsafe { nil } // current `$if` expr
|
||||||
}
|
}
|
||||||
|
|
||||||
@[heap]
|
@[heap]
|
||||||
|
@ -920,6 +925,11 @@ pub fn (mut g Gen) gen_file() {
|
||||||
g.inside_ternary = 0
|
g.inside_ternary = 0
|
||||||
}
|
}
|
||||||
g.stmts(g.file.stmts)
|
g.stmts(g.file.stmts)
|
||||||
|
|
||||||
|
// after all other stmts executed, we got info about hash stmts in top,
|
||||||
|
// write them to corresponding sections
|
||||||
|
g.gen_hash_stmts_in_top()
|
||||||
|
|
||||||
// Transfer embedded files
|
// Transfer embedded files
|
||||||
for path in g.file.embedded_files {
|
for path in g.file.embedded_files {
|
||||||
if path !in g.embedded_files {
|
if path !in g.embedded_files {
|
||||||
|
@ -5740,113 +5750,178 @@ fn (mut g Gen) hash_stmt_guarded_include(node ast.HashStmt) string {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn (mut g Gen) hash_stmt(node ast.HashStmt) {
|
fn (mut g Gen) hash_stmt(node ast.HashStmt) {
|
||||||
line_nr := node.pos.line_nr + 1
|
// we only record the hash stmt's node here, send it to corresponding `_nodes`, let `gen_hash_stmts_in_top()` gen the code.
|
||||||
mut ct_condition := ''
|
the_node := if g.comptime.inside_comptime_if && !isnil(g.curr_comptime_node)
|
||||||
|
&& g.curr_comptime_node is ast.IfExpr {
|
||||||
|
&ast.HashStmtNode(g.curr_comptime_node as ast.IfExpr)
|
||||||
|
} else {
|
||||||
|
&ast.HashStmtNode(&node)
|
||||||
|
}
|
||||||
|
|
||||||
if node.ct_conds.len > 0 {
|
match node.kind {
|
||||||
|
'include', 'insert', 'define' {
|
||||||
|
if node.main.contains('.m') {
|
||||||
|
// Objective C code import, include it after V types, so that e.g. `string` is
|
||||||
|
// available there
|
||||||
|
if the_node !in g.definition_nodes {
|
||||||
|
g.definition_nodes << the_node
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if the_node !in g.include_nodes {
|
||||||
|
g.include_nodes << the_node
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
'preinclude' {
|
||||||
|
if node.main.contains('.m') {
|
||||||
|
// Objective C code import, include it after V types, so that e.g. `string` is
|
||||||
|
// available there
|
||||||
|
if the_node !in g.definition_nodes {
|
||||||
|
g.definition_nodes << the_node
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if the_node !in g.preinclude_nodes {
|
||||||
|
g.preinclude_nodes << the_node
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
'postinclude' {
|
||||||
|
if the_node !in g.postinclude_nodes {
|
||||||
|
g.postinclude_nodes << the_node
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn (mut g Gen) gen_hash_stmts(mut sb strings.Builder, node &ast.HashStmtNode, section string) {
|
||||||
|
match node {
|
||||||
|
ast.IfExpr {
|
||||||
mut comptime_branch_context_str := g.gen_branch_context_string()
|
mut comptime_branch_context_str := g.gen_branch_context_string()
|
||||||
mut is_true := ast.ComptTimeCondResult{}
|
mut is_true := ast.ComptTimeCondResult{}
|
||||||
mut sb := strings.new_builder(256)
|
for i, branch in node.branches {
|
||||||
for idx, ct_expr in node.ct_conds {
|
idx_str := if branch.cond.pos() == token.Pos{} {
|
||||||
idx_str := comptime_branch_context_str + '|${g.file.path}|${ct_expr.pos()}|'
|
comptime_branch_context_str + '|${g.file.path}|${branch.pos}|'
|
||||||
|
} else {
|
||||||
|
comptime_branch_context_str + '|${g.file.path}|${branch.cond.pos()}|'
|
||||||
|
}
|
||||||
if comptime_is_true := g.table.comptime_is_true[idx_str] {
|
if comptime_is_true := g.table.comptime_is_true[idx_str] {
|
||||||
// `g.table.comptime_is_true` are the branch condition results set by `checker`
|
// `g.table.comptime_is_true` are the branch condition results set by `checker`
|
||||||
is_true = comptime_is_true
|
is_true = comptime_is_true
|
||||||
} else {
|
} else {
|
||||||
g.error('checker error: condition result idx string not found => [${idx_str}]',
|
g.error('checker error: condition result idx string not found => [${idx_str}]',
|
||||||
ct_expr.pos())
|
node.branches[i].cond.pos())
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
sb.write_string(is_true.c_str)
|
if !node.has_else || i < node.branches.len - 1 {
|
||||||
if idx < node.ct_conds.len - 1 {
|
if i == 0 {
|
||||||
sb.write_string(' && ')
|
sb.write_string('\n#if ')
|
||||||
|
} else {
|
||||||
|
sb.write_string('\n#elif ')
|
||||||
}
|
}
|
||||||
}
|
// directly use `checker` evaluate results
|
||||||
ct_condition = sb.str()
|
// for `cgen`, we can use `is_true.c_str` or `is_true.value` here
|
||||||
}
|
sb.writeln('${is_true.c_str}')
|
||||||
// #include etc
|
$if debug_comptime_branch_context ? {
|
||||||
if node.kind == 'include' {
|
sb.writeln('/* ${node.branches[i].cond} | generic=[${comptime_branch_context_str}] */')
|
||||||
guarded_include := g.hash_stmt_guarded_include(node)
|
|
||||||
if node.main.contains('.m') {
|
|
||||||
g.definitions.writeln('')
|
|
||||||
if ct_condition != '' {
|
|
||||||
g.definitions.writeln('#if ${ct_condition}')
|
|
||||||
}
|
|
||||||
// Objective C code import, include it after V types, so that e.g. `string` is
|
|
||||||
// available there
|
|
||||||
g.definitions.writeln('// added by module `${node.mod}`, file: ${os.file_name(node.source_file)}:${line_nr}:')
|
|
||||||
g.definitions.writeln(guarded_include)
|
|
||||||
if ct_condition != '' {
|
|
||||||
g.definitions.writeln('#endif // \$if ${ct_condition}')
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
g.includes.writeln('')
|
sb.writeln('#else')
|
||||||
if ct_condition != '' {
|
$if debug_comptime_branch_context ? {
|
||||||
g.includes.writeln('#if ${ct_condition}')
|
sb.writeln('/* else | generic=[${comptime_branch_context_str}] */')
|
||||||
}
|
|
||||||
g.includes.writeln('// added by module `${node.mod}`, file: ${os.file_name(node.source_file)}:${line_nr}:')
|
|
||||||
g.includes.writeln(guarded_include)
|
|
||||||
if ct_condition != '' {
|
|
||||||
g.includes.writeln('#endif // \$if ${ct_condition}')
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if node.kind == 'preinclude' {
|
if is_true.val || g.pref.output_cross_c {
|
||||||
guarded_include := g.hash_stmt_guarded_include(node)
|
// check only `IfExpr` and `HashStmt`
|
||||||
if node.main.contains('.m') {
|
for stmt in branch.stmts {
|
||||||
// Might need to support '#preinclude' for .m files as well but for the moment
|
if stmt is ast.ExprStmt {
|
||||||
// this does the same as '#include' for them
|
if stmt.expr is ast.IfExpr && (stmt.expr as ast.IfExpr).is_comptime {
|
||||||
g.definitions.writeln('')
|
g.gen_hash_stmts(mut sb, stmt.expr, section)
|
||||||
if ct_condition != '' {
|
|
||||||
g.definitions.writeln('#if ${ct_condition}')
|
|
||||||
}
|
}
|
||||||
|
} else if stmt is ast.HashStmt {
|
||||||
|
g.gen_hash_stmts(mut sb, stmt, section)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
sb.writeln('#endif')
|
||||||
|
}
|
||||||
|
ast.HashStmt {
|
||||||
|
// #preinclude => `preincludes` section
|
||||||
|
// #inlude,#define,#insert => `includes` section
|
||||||
|
// #postinclude => `postincludes` section
|
||||||
|
// '*.m' in #include or #preinclude => `definitions` section
|
||||||
|
need_gen_stmt := match section {
|
||||||
|
'preincludes' {
|
||||||
|
if node.kind == 'preinclude' && !node.main.contains('.m') { true } else { false }
|
||||||
|
}
|
||||||
|
'includes' {
|
||||||
|
if node.kind in ['include', 'define', 'insert'] && !node.main.contains('.m') {
|
||||||
|
true
|
||||||
|
} else {
|
||||||
|
false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
'definitions' {
|
||||||
// Objective C code import, include it after V types, so that e.g. `string` is
|
// Objective C code import, include it after V types, so that e.g. `string` is
|
||||||
// available there
|
// available there
|
||||||
g.definitions.writeln('// added by module `${node.mod}`, file: ${os.file_name(node.source_file)}:${line_nr}:')
|
if node.kind in ['include', 'preinclude'] && node.main.contains('.m') {
|
||||||
g.definitions.writeln(guarded_include)
|
true
|
||||||
if ct_condition != '' {
|
|
||||||
g.definitions.writeln('#endif // \$if ${ct_condition}')
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
g.preincludes.writeln('')
|
false
|
||||||
if ct_condition != '' {
|
|
||||||
g.preincludes.writeln('#if ${ct_condition}')
|
|
||||||
}
|
|
||||||
g.preincludes.writeln('// added by module `${node.mod}`, file: ${os.file_name(node.source_file)}:${line_nr}:')
|
|
||||||
g.preincludes.writeln(guarded_include)
|
|
||||||
if ct_condition != '' {
|
|
||||||
g.preincludes.writeln('#endif // \$if ${ct_condition}')
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if node.kind == 'postinclude' {
|
'postincludes' {
|
||||||
|
if node.kind == 'postinclude' { true } else { false }
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if !need_gen_stmt {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
line_nr := node.pos.line_nr + 1
|
||||||
|
match node.kind {
|
||||||
|
'include', 'preinclude', 'postinclude' {
|
||||||
guarded_include := g.hash_stmt_guarded_include(node)
|
guarded_include := g.hash_stmt_guarded_include(node)
|
||||||
g.postincludes.writeln('')
|
sb.writeln('')
|
||||||
if ct_condition != '' {
|
sb.writeln('// added by module `${node.mod}`, file: ${os.file_name(node.source_file)}:${line_nr}:')
|
||||||
g.postincludes.writeln('#if ${ct_condition}')
|
sb.writeln(guarded_include)
|
||||||
}
|
}
|
||||||
g.postincludes.writeln('// added by module `${node.mod}`, file: ${os.file_name(node.source_file)}:${line_nr}:')
|
'insert' {
|
||||||
g.postincludes.writeln(guarded_include)
|
sb.writeln('')
|
||||||
if ct_condition != '' {
|
sb.writeln('// inserted by module `${node.mod}`, file: ${os.file_name(node.source_file)}:${line_nr}:')
|
||||||
g.postincludes.writeln('#endif // \$if ${ct_condition}')
|
sb.writeln(node.val)
|
||||||
}
|
}
|
||||||
} else if node.kind == 'insert' {
|
'define' {
|
||||||
if ct_condition != '' {
|
sb.writeln('// defined by module `${node.mod}`')
|
||||||
g.includes.writeln('#if ${ct_condition}')
|
sb.writeln('#define ${node.main}')
|
||||||
}
|
}
|
||||||
g.includes.writeln('// inserted by module `${node.mod}`, file: ${os.file_name(node.source_file)}:${line_nr}:')
|
else {}
|
||||||
g.includes.writeln(node.val)
|
|
||||||
if ct_condition != '' {
|
|
||||||
g.includes.writeln('#endif // \$if ${ct_condition}')
|
|
||||||
}
|
|
||||||
} else if node.kind == 'define' {
|
|
||||||
if ct_condition != '' {
|
|
||||||
g.includes.writeln('#if ${ct_condition}')
|
|
||||||
}
|
|
||||||
g.includes.writeln('// defined by module `${node.mod}`')
|
|
||||||
g.includes.writeln('#define ${node.main}')
|
|
||||||
if ct_condition != '' {
|
|
||||||
g.includes.writeln('#endif // \$if ${ct_condition}')
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// TODO: support $match
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn (mut g Gen) gen_hash_stmts_in_top() {
|
||||||
|
for node in g.preinclude_nodes {
|
||||||
|
g.gen_hash_stmts(mut g.preincludes, node, 'preincludes')
|
||||||
|
}
|
||||||
|
for node in g.include_nodes {
|
||||||
|
g.gen_hash_stmts(mut g.includes, node, 'includes')
|
||||||
|
}
|
||||||
|
for node in g.definition_nodes {
|
||||||
|
g.gen_hash_stmts(mut g.definitions, node, 'definitions')
|
||||||
|
}
|
||||||
|
for node in g.postinclude_nodes {
|
||||||
|
g.gen_hash_stmts(mut g.postincludes, node, 'postincludes')
|
||||||
|
}
|
||||||
|
g.preinclude_nodes.clear()
|
||||||
|
g.include_nodes.clear()
|
||||||
|
g.definition_nodes.clear()
|
||||||
|
g.postinclude_nodes.clear()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn (mut g Gen) branch_stmt(node ast.BranchStmt) {
|
fn (mut g Gen) branch_stmt(node ast.BranchStmt) {
|
||||||
|
|
|
@ -401,9 +401,20 @@ fn (mut g Gen) comptime_if(node ast.IfExpr) {
|
||||||
''
|
''
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// save node for processing hash stmts
|
||||||
|
// we only save the first node, when there is embedded $if
|
||||||
|
old_curr_comptime_node := g.curr_comptime_node
|
||||||
|
if !g.comptime.inside_comptime_if {
|
||||||
|
g.curr_comptime_node = &node
|
||||||
|
}
|
||||||
|
defer {
|
||||||
|
g.curr_comptime_node = old_curr_comptime_node
|
||||||
|
}
|
||||||
mut comptime_branch_context_str := g.gen_branch_context_string()
|
mut comptime_branch_context_str := g.gen_branch_context_string()
|
||||||
mut is_true := ast.ComptTimeCondResult{}
|
mut is_true := ast.ComptTimeCondResult{}
|
||||||
for i, branch in node.branches {
|
for i, branch in node.branches {
|
||||||
|
g.push_new_comptime_info()
|
||||||
|
g.comptime.inside_comptime_if = true
|
||||||
start_pos := g.out.len
|
start_pos := g.out.len
|
||||||
// `idx_str` is composed of two parts:
|
// `idx_str` is composed of two parts:
|
||||||
// The first part represents the current context of the branch statement, `comptime_branch_context_str`, formatted like `T=int,X=string,method.name=json`
|
// The first part represents the current context of the branch statement, `comptime_branch_context_str`, formatted like `T=int,X=string,method.name=json`
|
||||||
|
@ -501,6 +512,7 @@ fn (mut g Gen) comptime_if(node ast.IfExpr) {
|
||||||
g.writeln('}')
|
g.writeln('}')
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
g.pop_comptime_info()
|
||||||
}
|
}
|
||||||
g.defer_ifdef = ''
|
g.defer_ifdef = ''
|
||||||
g.writeln('#endif')
|
g.writeln('#endif')
|
||||||
|
@ -563,6 +575,7 @@ fn (mut g Gen) push_new_comptime_info() {
|
||||||
g.type_resolver.info_stack << type_resolver.ResolverInfo{
|
g.type_resolver.info_stack << type_resolver.ResolverInfo{
|
||||||
saved_type_map: g.type_resolver.type_map.clone()
|
saved_type_map: g.type_resolver.type_map.clone()
|
||||||
inside_comptime_for: g.comptime.inside_comptime_for
|
inside_comptime_for: g.comptime.inside_comptime_for
|
||||||
|
inside_comptime_if: g.comptime.inside_comptime_if
|
||||||
comptime_for_variant_var: g.comptime.comptime_for_variant_var
|
comptime_for_variant_var: g.comptime.comptime_for_variant_var
|
||||||
comptime_for_field_var: g.comptime.comptime_for_field_var
|
comptime_for_field_var: g.comptime.comptime_for_field_var
|
||||||
comptime_for_field_type: g.comptime.comptime_for_field_type
|
comptime_for_field_type: g.comptime.comptime_for_field_type
|
||||||
|
@ -582,6 +595,7 @@ fn (mut g Gen) pop_comptime_info() {
|
||||||
old := g.type_resolver.info_stack.pop()
|
old := g.type_resolver.info_stack.pop()
|
||||||
g.type_resolver.type_map = old.saved_type_map.clone()
|
g.type_resolver.type_map = old.saved_type_map.clone()
|
||||||
g.comptime.inside_comptime_for = old.inside_comptime_for
|
g.comptime.inside_comptime_for = old.inside_comptime_for
|
||||||
|
g.comptime.inside_comptime_if = old.inside_comptime_if
|
||||||
g.comptime.comptime_for_variant_var = old.comptime_for_variant_var
|
g.comptime.comptime_for_variant_var = old.comptime_for_variant_var
|
||||||
g.comptime.comptime_for_field_var = old.comptime_for_field_var
|
g.comptime.comptime_for_field_var = old.comptime_for_field_var
|
||||||
g.comptime.comptime_for_field_type = old.comptime_for_field_type
|
g.comptime.comptime_for_field_type = old.comptime_for_field_type
|
||||||
|
|
52
vlib/v/gen/c/testdata/comptime_if_top_hash_stmts.c.must_have
vendored
Normal file
52
vlib/v/gen/c/testdata/comptime_if_top_hash_stmts.c.must_have
vendored
Normal file
|
@ -0,0 +1,52 @@
|
||||||
|
#if defined(_WIN32)
|
||||||
|
#if defined(CUSTOM_DEFINE_user_d1)
|
||||||
|
#elif defined(CUSTOM_DEFINE_user_d2)
|
||||||
|
#include "pre1.h"
|
||||||
|
#elif defined(__linux__)
|
||||||
|
#if defined(CUSTOM_DEFINE_user_d3)
|
||||||
|
#include "pre2.h"
|
||||||
|
#elif defined(CUSTOM_DEFINE_user_d4)
|
||||||
|
#if defined(_WIN32)
|
||||||
|
#if defined(CUSTOM_DEFINE_user_d1)
|
||||||
|
#include "w1.h"
|
||||||
|
#define user_d1
|
||||||
|
#elif defined(CUSTOM_DEFINE_user_d2)
|
||||||
|
#include "w2.h"
|
||||||
|
#define user_d2
|
||||||
|
#else
|
||||||
|
#include "w3.h"
|
||||||
|
#define user_not_d1_d2
|
||||||
|
#define user_all_windows
|
||||||
|
#include "windows.h"
|
||||||
|
#elif defined(__linux__)
|
||||||
|
#if defined(CUSTOM_DEFINE_user_d3)
|
||||||
|
#include "l1.h"
|
||||||
|
#define user_d3
|
||||||
|
#elif defined(CUSTOM_DEFINE_user_d4)
|
||||||
|
#include "l2.h"
|
||||||
|
#define user_d4
|
||||||
|
#define user_all_linux
|
||||||
|
#include "stdio.h"
|
||||||
|
#else
|
||||||
|
#define user_all_other
|
||||||
|
#include "other.h"
|
||||||
|
#if defined(_WIN32)
|
||||||
|
#if defined(CUSTOM_DEFINE_user_d1)
|
||||||
|
#elif defined(CUSTOM_DEFINE_user_d2)
|
||||||
|
#else
|
||||||
|
#include "macos1.m"
|
||||||
|
#elif defined(__linux__)
|
||||||
|
#if defined(CUSTOM_DEFINE_user_d3)
|
||||||
|
#include "macos2.m"
|
||||||
|
#elif defined(CUSTOM_DEFINE_user_d4)
|
||||||
|
#endif
|
||||||
|
#if defined(_WIN32)
|
||||||
|
#if defined(CUSTOM_DEFINE_user_d1)
|
||||||
|
#elif defined(CUSTOM_DEFINE_user_d2)
|
||||||
|
#include "post1.h"
|
||||||
|
#elif defined(__linux__)
|
||||||
|
#if defined(CUSTOM_DEFINE_user_d3)
|
||||||
|
#elif defined(CUSTOM_DEFINE_user_d4)
|
||||||
|
#include "post2.h"
|
||||||
|
#else
|
||||||
|
#include "post3.h"
|
40
vlib/v/gen/c/testdata/comptime_if_top_hash_stmts.vv
vendored
Normal file
40
vlib/v/gen/c/testdata/comptime_if_top_hash_stmts.vv
vendored
Normal file
|
@ -0,0 +1,40 @@
|
||||||
|
// vtest vflags: -os cross
|
||||||
|
module main
|
||||||
|
|
||||||
|
$if windows {
|
||||||
|
$if user_d1 ? {
|
||||||
|
#include "w1.h"
|
||||||
|
#define user_d1
|
||||||
|
} $else $if user_d2 ? {
|
||||||
|
#include "w2.h"
|
||||||
|
#define user_d2
|
||||||
|
#preinclude "pre1.h"
|
||||||
|
} $else {
|
||||||
|
#include "w3.h"
|
||||||
|
#define user_not_d1_d2
|
||||||
|
#include "macos1.m"
|
||||||
|
#postinclude "post1.h"
|
||||||
|
}
|
||||||
|
#define user_all_windows
|
||||||
|
#include "windows.h"
|
||||||
|
} $else $if linux {
|
||||||
|
$if user_d3 ? {
|
||||||
|
#include "l1.h"
|
||||||
|
#include "macos2.m"
|
||||||
|
#define user_d3
|
||||||
|
#preinclude "pre2.h"
|
||||||
|
} $else $if user_d4 ? {
|
||||||
|
#include "l2.h"
|
||||||
|
#define user_d4
|
||||||
|
#postinclude "post2.h"
|
||||||
|
}
|
||||||
|
#define user_all_linux
|
||||||
|
#include "stdio.h"
|
||||||
|
} $else {
|
||||||
|
#define user_all_other
|
||||||
|
#include "other.h"
|
||||||
|
#postinclude "post3.h"
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
}
|
Loading…
Add table
Add a link
Reference in a new issue