mirror of
https://github.com/c3lang/c3c.git
synced 2026-02-27 12:01:16 +00:00
Updated winmain handling
This commit is contained in:
committed by
Christoffer Lerno
parent
52d7e58c19
commit
77608e137e
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -788,6 +788,7 @@ typedef enum
|
||||
ATTRIBUTE_VECCALL,
|
||||
ATTRIBUTE_WASM,
|
||||
ATTRIBUTE_WEAK,
|
||||
ATTRIBUTE_WINMAIN,
|
||||
ATTRIBUTE_NONE,
|
||||
NUMBER_OF_ATTRIBUTES = ATTRIBUTE_NONE,
|
||||
} AttributeType;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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++)
|
||||
{
|
||||
|
||||
@@ -1 +1 @@
|
||||
#define COMPILER_VERSION "0.4.29"
|
||||
#define COMPILER_VERSION "0.4.30"
|
||||
Reference in New Issue
Block a user