mirror of
https://github.com/vlang/v.git
synced 2023-08-10 21:13:21 +03:00
Change CGen so that v.c is compileable with msvc
This commit is contained in:
parent
41f4ec5a3b
commit
049d78a78d
@ -493,9 +493,9 @@ fn (p mut Parser) async_fn_call(f Fn, method_ph int, receiver_var, receiver_type
|
|||||||
did_gen_something = true
|
did_gen_something = true
|
||||||
}
|
}
|
||||||
|
|
||||||
if p.os == .msvc && !did_gen_something {
|
if !did_gen_something {
|
||||||
// Msvc doesnt like empty struct
|
// Msvc doesnt like empty struct
|
||||||
arg_struct += 'void *____dummy_variable;'
|
arg_struct += 'EMPTY_STRUCT_DECLARATION'
|
||||||
}
|
}
|
||||||
|
|
||||||
arg_struct += '} $arg_struct_name ;'
|
arg_struct += '} $arg_struct_name ;'
|
||||||
|
@ -189,6 +189,10 @@ fn (v mut V) compile() {
|
|||||||
#include <stdarg.h> // for va_list
|
#include <stdarg.h> // for va_list
|
||||||
#include <inttypes.h> // int64_t etc
|
#include <inttypes.h> // int64_t etc
|
||||||
|
|
||||||
|
#define STRUCT_DEFAULT_VALUE {}
|
||||||
|
#define EMPTY_STRUCT_DECLARATION
|
||||||
|
#define EMPTY_STRUCT_INIT
|
||||||
|
#define OPTION_CAST(x) (x)
|
||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
#define WIN32_LEAN_AND_MEAN
|
#define WIN32_LEAN_AND_MEAN
|
||||||
@ -201,6 +205,15 @@ fn (v mut V) compile() {
|
|||||||
#ifdef _MSC_VER
|
#ifdef _MSC_VER
|
||||||
// On MSVC these are the same (as long as /volatile:ms is passed)
|
// On MSVC these are the same (as long as /volatile:ms is passed)
|
||||||
#define _Atomic volatile
|
#define _Atomic volatile
|
||||||
|
|
||||||
|
// MSVC can\'t parse some things properly
|
||||||
|
#undef STRUCT_DEFAULT_VALUE
|
||||||
|
#define STRUCT_DEFAULT_VALUE {0}
|
||||||
|
#undef EMPTY_STRUCT_DECLARATION
|
||||||
|
#define EMPTY_STRUCT_DECLARATION void *____dummy_variable;
|
||||||
|
#undef EMPTY_STRUCT_INIT
|
||||||
|
#define EMPTY_STRUCT_INIT 0
|
||||||
|
#define OPTION_CAST(x)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
void pthread_mutex_lock(HANDLE *m) {
|
void pthread_mutex_lock(HANDLE *m) {
|
||||||
|
@ -618,8 +618,8 @@ fn (p mut Parser) struct_decl() {
|
|||||||
|
|
||||||
p.check(.rcbr)
|
p.check(.rcbr)
|
||||||
if !is_c {
|
if !is_c {
|
||||||
if p.os == .msvc && !did_gen_something {
|
if !did_gen_something {
|
||||||
p.gen_type('void *____dummy_variable; };')
|
p.gen_type('EMPTY_STRUCT_DECLARATION };')
|
||||||
p.fgenln('')
|
p.fgenln('')
|
||||||
} else {
|
} else {
|
||||||
p.gen_type('}; ')
|
p.gen_type('}; ')
|
||||||
@ -1895,7 +1895,7 @@ fn (p mut Parser) index_expr(typ string, fn_ph int) string {
|
|||||||
if is_map {
|
if is_map {
|
||||||
p.gen('$tmp')
|
p.gen('$tmp')
|
||||||
mut def := type_default(typ)
|
mut def := type_default(typ)
|
||||||
if p.os == .msvc && def == '{}' {
|
if def == 'STRUCT_DEFAULT_VALUE' {
|
||||||
def = '{0}'
|
def = '{0}'
|
||||||
}
|
}
|
||||||
p.cgen.insert_before('$typ $tmp = $def; bool $tmp_ok = map_get($index_expr, & $tmp);')
|
p.cgen.insert_before('$typ $tmp = $def; bool $tmp_ok = map_get($index_expr, & $tmp);')
|
||||||
@ -2025,7 +2025,7 @@ fn (p mut Parser) expression() string {
|
|||||||
}
|
}
|
||||||
// 3 + 4
|
// 3 + 4
|
||||||
else if is_num {
|
else if is_num {
|
||||||
if p.os == .msvc && typ == 'void*' {
|
if typ == 'void*' {
|
||||||
// Msvc errors on void* pointer arithmatic
|
// Msvc errors on void* pointer arithmatic
|
||||||
// ... So cast to byte* and then do the add
|
// ... So cast to byte* and then do the add
|
||||||
p.cgen.set_placeholder(ph, '(byte*)')
|
p.cgen.set_placeholder(ph, '(byte*)')
|
||||||
@ -2467,11 +2467,7 @@ fn (p mut Parser) array_init() string {
|
|||||||
name := p.check_name()
|
name := p.check_name()
|
||||||
if p.table.known_type(name) {
|
if p.table.known_type(name) {
|
||||||
p.cgen.resetln('')
|
p.cgen.resetln('')
|
||||||
if p.os == .msvc {
|
p.gen('STRUCT_DEFAULT_VALUE')
|
||||||
p.gen('{0}')
|
|
||||||
} else {
|
|
||||||
p.gen('{}')
|
|
||||||
}
|
|
||||||
return '[$lit]$name'
|
return '[$lit]$name'
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
@ -2555,8 +2551,8 @@ fn (p mut Parser) array_init() string {
|
|||||||
// p.gen('$new_arr($vals.len, $vals.len, sizeof($typ), ($typ[]) $c_arr );')
|
// p.gen('$new_arr($vals.len, $vals.len, sizeof($typ), ($typ[]) $c_arr );')
|
||||||
// TODO why need !first_run()?? Otherwise it goes to the very top of the out.c file
|
// TODO why need !first_run()?? Otherwise it goes to the very top of the out.c file
|
||||||
if !p.first_run() {
|
if !p.first_run() {
|
||||||
if p.os == .msvc && i == 0 {
|
if i == 0 {
|
||||||
p.cgen.set_placeholder(new_arr_ph, '$new_arr($i, $i, sizeof($typ), ($typ[]) {0 ')
|
p.cgen.set_placeholder(new_arr_ph, '$new_arr($i, $i, sizeof($typ), ($typ[]) {EMPTY_STRUCT_INIT ')
|
||||||
} else {
|
} else {
|
||||||
p.cgen.set_placeholder(new_arr_ph, '$new_arr($i, $i, sizeof($typ), ($typ[]) { ')
|
p.cgen.set_placeholder(new_arr_ph, '$new_arr($i, $i, sizeof($typ), ($typ[]) { ')
|
||||||
}
|
}
|
||||||
@ -2666,7 +2662,7 @@ fn (p mut Parser) struct_init(is_c_struct_init bool) string {
|
|||||||
p.error('pointer field `${typ}.${field.name}` must be initialized')
|
p.error('pointer field `${typ}.${field.name}` must be initialized')
|
||||||
}
|
}
|
||||||
def_val := type_default(field_typ)
|
def_val := type_default(field_typ)
|
||||||
if def_val != '' && def_val != '{}' {
|
if def_val != '' && def_val != 'STRUCT_DEFAULT_VALUE' {
|
||||||
p.gen('.$field.name = $def_val')
|
p.gen('.$field.name = $def_val')
|
||||||
if i != t.fields.len - 1 {
|
if i != t.fields.len - 1 {
|
||||||
p.gen(',')
|
p.gen(',')
|
||||||
@ -2706,8 +2702,8 @@ fn (p mut Parser) struct_init(is_c_struct_init bool) string {
|
|||||||
did_gen_something = true
|
did_gen_something = true
|
||||||
}
|
}
|
||||||
|
|
||||||
if p.os == .msvc && !did_gen_something {
|
if !did_gen_something {
|
||||||
p.gen('0')
|
p.gen('EMPTY_STRUCT_INIT')
|
||||||
}
|
}
|
||||||
|
|
||||||
p.gen('}')
|
p.gen('}')
|
||||||
@ -3108,7 +3104,7 @@ fn (p mut Parser) for_st() {
|
|||||||
p.genln(' string $i = ((string*)keys_$tmp .data)[l];')
|
p.genln(' string $i = ((string*)keys_$tmp .data)[l];')
|
||||||
//p.genln(' string $i = *(string*) ( array__get(keys_$tmp, l) );')
|
//p.genln(' string $i = *(string*) ( array__get(keys_$tmp, l) );')
|
||||||
mut def := type_default(typ)
|
mut def := type_default(typ)
|
||||||
if def == '{}' {
|
if def == 'STRUCT_DEFAULT_VALUE' {
|
||||||
def = '{0}'
|
def = '{0}'
|
||||||
}
|
}
|
||||||
// TODO don't call map_get() for each key, fetch values while traversing
|
// TODO don't call map_get() for each key, fetch values while traversing
|
||||||
@ -3293,15 +3289,8 @@ fn (p mut Parser) return_st() {
|
|||||||
tmp := p.get_tmp()
|
tmp := p.get_tmp()
|
||||||
ret := p.cgen.cur_line.right(ph)
|
ret := p.cgen.cur_line.right(ph)
|
||||||
|
|
||||||
if p.os != .msvc {
|
p.cgen.cur_line = '$expr_type $tmp = OPTION_CAST($expr_type)($ret);'
|
||||||
p.cgen.cur_line = '$expr_type $tmp = ($expr_type)($ret);'
|
p.cgen.resetln('$expr_type $tmp = OPTION_CAST($expr_type)($ret);')
|
||||||
p.cgen.resetln('$expr_type $tmp = ($expr_type)($ret);')
|
|
||||||
} else {
|
|
||||||
// Both the return type and the expression type have already been concluded
|
|
||||||
// to be the same - the cast is slightly pointless
|
|
||||||
// and msvc cant do it
|
|
||||||
p.cgen.resetln('$expr_type $tmp = ($ret);')
|
|
||||||
}
|
|
||||||
p.gen('return opt_ok(&$tmp, sizeof($expr_type))')
|
p.gen('return opt_ok(&$tmp, sizeof($expr_type))')
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
@ -544,7 +544,7 @@ fn type_default(typ string) string {
|
|||||||
}
|
}
|
||||||
// User struct defined in another module.
|
// User struct defined in another module.
|
||||||
if typ.contains('__') {
|
if typ.contains('__') {
|
||||||
return '{}'
|
return 'STRUCT_DEFAULT_VALUE'
|
||||||
}
|
}
|
||||||
// Default values for other types are not needed because of mandatory initialization
|
// Default values for other types are not needed because of mandatory initialization
|
||||||
switch typ {
|
switch typ {
|
||||||
@ -566,7 +566,7 @@ fn type_default(typ string) string {
|
|||||||
case 'byteptr': return '0'
|
case 'byteptr': return '0'
|
||||||
case 'voidptr': return '0'
|
case 'voidptr': return '0'
|
||||||
}
|
}
|
||||||
return '{}'
|
return 'STRUCT_DEFAULT_VALUE'
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO PERF O(n)
|
// TODO PERF O(n)
|
||||||
|
Loading…
Reference in New Issue
Block a user