Updated winmain handling

This commit is contained in:
Christoffer Lerno
2023-01-29 12:41:09 +01:00
committed by Christoffer Lerno
parent 52d7e58c19
commit 77608e137e
10 changed files with 40 additions and 30 deletions

View File

@@ -129,7 +129,6 @@ static void usage(void)
OUTPUT(" -z <argument> - Send the <argument> as a parameter to the linker.");
OUTPUT(" --forcelinker - Force built in linker usage when doing non-cross linking.");
OUTPUT("");
OUTPUT(" --gui - Build a 'gui' variant of the executable (e.g. '/SUBSYSTEM:WINDOWS' on Win32).");
OUTPUT(" --reloc=<option> - Relocation model: none, pic, PIC, pie, PIE.");
OUTPUT(" --x86vec=<option> - Set max level of vector instructions: none, native, mmx, sse, avx, avx512.");
OUTPUT(" --memory-env=<option> - Set the memory environment: normal, small, tiny, none.");
@@ -533,11 +532,6 @@ static void parse_option(BuildOptions *options)
options->symtab_size = next_highest_power_of_2(symtab);
return;
}
if (match_longopt("gui"))
{
options->gui = true;
return;
}
if (match_longopt("forcelinker"))
{
options->force_linker = true;

View File

@@ -290,7 +290,6 @@ typedef struct BuildOptions_
bool no_stdlib;
bool no_entry;
bool no_libc;
bool gui;
bool force_linker;
bool read_stdin;
bool print_output;
@@ -375,7 +374,6 @@ typedef struct
bool emit_asm;
bool no_stdlib;
bool no_libc;
bool gui;
bool emit_object_files;
bool force_linker;
bool benchmarking;
@@ -417,6 +415,7 @@ typedef struct
{
const char *sdk;
WinCrtLinking crt_linking;
bool use_win_subsystem;
} win;
} BuildTarget;

View File

@@ -233,7 +233,6 @@ static void update_build_target_from_options(BuildTarget *target, BuildOptions *
target->panicfn = options->panicfn;
target->benchmarking = options->benchmarking;
target->testing = options->testing;
if (options->gui) target->gui = true;
if (options->macos.sdk) target->macos.sdk = options->macos.sdk;
if (options->win.sdk) target->win.sdk = options->win.sdk;
if (options->macos.min_version) target->macos.min_version = options->macos.min_version;

View File

@@ -362,9 +362,6 @@ static void load_into_build_target(JSONObject *json, const char *type, BuildTarg
// nolibc
target->no_libc = get_valid_bool(json, "nolibc", type, target->no_libc);
// gui
target->gui = get_valid_bool(json, "gui", type, target->gui);
// no-entry
target->no_entry = get_valid_bool(json, "no-entry", type, target->no_entry);

View File

@@ -559,6 +559,7 @@ typedef struct
bool attr_extname : 1;
bool attr_naked : 1;
bool attr_test : 1;
bool attr_winmain : 1;
Decl** generated_lambda;
};
struct

View File

@@ -788,6 +788,7 @@ typedef enum
ATTRIBUTE_VECCALL,
ATTRIBUTE_WASM,
ATTRIBUTE_WEAK,
ATTRIBUTE_WINMAIN,
ATTRIBUTE_NONE,
NUMBER_OF_ATTRIBUTES = ATTRIBUTE_NONE,
} AttributeType;

View File

@@ -77,7 +77,7 @@ static const char *string_esc(const char *str)
}
static void linker_setup_windows(const char ***args_ref, LinkerType linker_type)
{
add_arg(active_target.gui ? "/SUBSYSTEM:WINDOWS" : "/SUBSYSTEM:CONSOLE");
add_arg(active_target.win.use_win_subsystem ? "/SUBSYSTEM:WINDOWS" : "/SUBSYSTEM:CONSOLE");
if (linker_type == LINKER_CC) return;
//add_arg("/MACHINE:X64");
bool is_debug = false;

View File

@@ -1465,8 +1465,9 @@ static bool sema_analyse_attribute(SemaContext *context, Decl *decl, Attr *attr,
[ATTRIBUTE_UNUSED] = (AttributeDomain)~(ATTR_CALL | ATTR_XXLIZER),
[ATTRIBUTE_USED] = (AttributeDomain)~(ATTR_CALL | ATTR_XXLIZER ),
[ATTRIBUTE_VECCALL] = ATTR_FUNC,
[ATTRIBUTE_WEAK] = ATTR_FUNC | ATTR_CONST | ATTR_GLOBAL,
[ATTRIBUTE_WASM] = ATTR_FUNC,
[ATTRIBUTE_WEAK] = ATTR_FUNC | ATTR_CONST | ATTR_GLOBAL,
[ATTRIBUTE_WINMAIN] = ATTR_FUNC,
};
if ((attribute_domain[type] & domain) != domain)
@@ -1483,6 +1484,14 @@ static bool sema_analyse_attribute(SemaContext *context, Decl *decl, Attr *attr,
Expr *expr = args ? attr->exprs[0] : NULL;
switch (type)
{
case ATTRIBUTE_WINMAIN:
if (decl->name != kw_main)
{
SEMA_ERROR(attr, "'@winmain' can only be used on the 'main' function.");
return false;
}
decl->func_decl.attr_winmain = true;
break;
case ATTRIBUTE_CDECL:
decl->func_decl.signature.abi = CALL_C;
break;
@@ -1881,7 +1890,7 @@ ADDED:;
return true;
}
static inline MainType sema_find_main_type(SemaContext *context, Signature *sig)
static inline MainType sema_find_main_type(SemaContext *context, Signature *sig, bool is_winmain)
{
Decl **params = sig->params;
unsigned param_count = vec_size(params);
@@ -1912,9 +1921,14 @@ static inline MainType sema_find_main_type(SemaContext *context, Signature *sig)
SEMA_ERROR(params[1], "Expected a parameter of type 'char**' for a C-style main.");
return MAIN_TYPE_ERROR;
}
if (is_winmain)
{
SEMA_ERROR(params[0], "For '@winmain' functions, C-style 'main' with argc + argv isn't valid. It compiles if you remove the '@winmain' attribute.");
return MAIN_TYPE_ERROR;
}
return MAIN_TYPE_RAW;
case 3:
if (!is_win32) break;
if (!is_win32 || is_winmain) break;
arg_type = type_flatten_distinct(params[0]->type);
arg_type2 = type_flatten_distinct(params[1]->type);
if (arg_type != type_voidptr)
@@ -1933,11 +1947,16 @@ static inline MainType sema_find_main_type(SemaContext *context, Signature *sig)
type_quoted_error_string(type_cint));
return MAIN_TYPE_ERROR;
}
if (!is_win32)
{
SEMA_ERROR(params[0], "'main(HINSTANCE, String[], int) is only valid for Windows.");
return MAIN_TYPE_ERROR;
}
return MAIN_TYPE_WIN;
default:
break;
}
SEMA_ERROR(params[0], is_win32
SEMA_ERROR(params[0], (is_win32 & is_winmain)
? "Expected zero, 1 or 3 parameters for main."
: "Expected zero or 1 parameters for main.");
return MAIN_TYPE_ERROR;
@@ -2079,6 +2098,7 @@ static inline Decl *sema_create_synthetic_win_main(SemaContext *context, Decl *d
function->name = kw_mainstub;
function->unit = decl->unit;
function->extname = kw_winmain;
function->func_decl.attr_winmain = true;
function->has_extname = true;
function->func_decl.signature.rtype = type_infoid(type_info_new_base(type_cint, decl->span));
function->func_decl.signature.vararg_index = 3;
@@ -2156,7 +2176,8 @@ NEXT:;
static inline bool sema_analyse_main_function(SemaContext *context, Decl *decl)
{
assert(decl != context->unit->main_function);
bool is_winmain = decl->func_decl.attr_winmain;
bool is_win32 = platform_target.os == OS_TYPE_WIN32;
if (decl->visibility == VISIBLE_LOCAL)
{
SEMA_ERROR(decl, "A main function may not have local visibility.");
@@ -2186,7 +2207,7 @@ static inline bool sema_analyse_main_function(SemaContext *context, Decl *decl)
return false;
}
// At this point the style is either MAIN_INT_VOID, MAIN_VOID_VOID or MAIN_ERR_VOID
MainType type = sema_find_main_type(context, signature);
MainType type = sema_find_main_type(context, signature, is_winmain);
if (type == MAIN_TYPE_ERROR) return false;
if (active_target.type == TARGET_TYPE_TEST) return true;
Decl *function;
@@ -2200,17 +2221,20 @@ static inline bool sema_analyse_main_function(SemaContext *context, Decl *decl)
SEMA_ERROR(rtype_info, "Int return is required for C style main.");
return false;
}
if ((type == MAIN_TYPE_RAW || type == MAIN_TYPE_NO_ARGS) && is_int_return && !active_target.gui)
// Suppress winmain on non-win32
if (platform_target.os != OS_TYPE_WIN32) is_winmain = false;
if ((type == MAIN_TYPE_RAW || type == MAIN_TYPE_NO_ARGS) && is_int_return && !is_winmain)
{
// Int return is pass-through at the moment.
decl->visibility = VISIBLE_EXTERN;
function = decl;
goto REGISTER_MAIN;
}
if (platform_target.os == OS_TYPE_WIN32)
if (is_win32)
{
function = active_target.gui
active_target.win.use_win_subsystem = is_winmain;
function = is_winmain
? sema_create_synthetic_win_main(context, decl, type, is_int_return, is_err_return)
: sema_create_synthetic_wmain(context, decl, type, is_int_return, is_err_return);
}

View File

@@ -40,12 +40,6 @@ const char *attribute_list[NUMBER_OF_ATTRIBUTES];
const char *builtin_list[NUMBER_OF_BUILTINS];
const char *builtin_defines[NUMBER_OF_BUILTIN_DEFINES];
const char *type_property_list[NUMBER_OF_TYPE_PROPERTIES];
const char *kw_FILE;
const char *kw_FUNC;
const char *kw_FUNCPTR;
const char *kw_LINEREAL;
const char *kw_LINE;
const char *kw_align;
const char *kw_argc;
const char *kw_argv;
const char *kw_at_checked;
@@ -321,6 +315,7 @@ void symtab_init(uint32_t capacity)
attribute_list[ATTRIBUTE_VECCALL] = KW_DEF("@veccall");
attribute_list[ATTRIBUTE_WASM] = KW_DEF("@wasm");
attribute_list[ATTRIBUTE_WEAK] = KW_DEF("@weak");
attribute_list[ATTRIBUTE_WINMAIN] = KW_DEF("@winmain");
for (unsigned i = 0; i < NUMBER_OF_ATTRIBUTES; i++)
{

View File

@@ -1 +1 @@
#define COMPILER_VERSION "0.4.29"
#define COMPILER_VERSION "0.4.30"