diff --git a/src/link/lldc/lldc.c b/src/link/lldc/lldc.c index aad0e56..274ecc4 100644 --- a/src/link/lldc/lldc.c +++ b/src/link/lldc/lldc.c @@ -11,7 +11,8 @@ extern int lld_main(int Argc, const char **Argv, const char **outstr); const char* FLAGS[] = { - "--fatal-warnings" + "--fatal-warnings", + "--nostdlib" }; const char* get_optimization_level_string(TargetConfig* config) @@ -35,6 +36,11 @@ bool lldc_link(TargetConfig* target_config, TargetLinkConfig* link_config) { g_array_append_val(arguments, colored_diagnostics); } + if (link_config->entry != NULL) { + char* colored_diagnostics = mem_asprintf(MemoryNamespaceLld, "--entry=%s", link_config->entry); + g_array_append_val(arguments, colored_diagnostics); + } + const char* optimization_level = get_optimization_level_string(target_config); g_array_append_val(arguments, optimization_level); diff --git a/src/llvm/link/lld.c b/src/llvm/link/lld.c index 385304c..90b4c62 100644 --- a/src/llvm/link/lld.c +++ b/src/llvm/link/lld.c @@ -55,6 +55,7 @@ TargetLinkConfig* lld_create_link_config(__attribute__((unused)) mem_new_g_array(MemoryNamespaceLld, sizeof(char*)); config->colorize = stdout_supports_ansi_esc(); config->driver = target_config->driver; + config->entry = module->entry; // append build object file char* basename = g_strjoin(".", target_config->name, "o", NULL); diff --git a/src/mem/cache.c b/src/mem/cache.c index dcbcf0f..fab3c87 100644 --- a/src/mem/cache.c +++ b/src/mem/cache.c @@ -369,3 +369,19 @@ GHashTable* mem_new_g_hash_table(MemoryNamespaceName name, GHashFunc hash_func, return namespace_new_g_hash_table(cache, hash_func, key_equal_func); } + +char* mem_asprintf(MemoryNamespaceName name, const char* format, ...) { + va_list args; + va_start(args, fmt); + + char* buffer = NULL; + int chars = vasprintf(&buffer, format, args); + + va_end(args); + + char* cached = mem_clone(name, buffer, chars); + + free(buffer); + + return cached; +} diff --git a/src/mem/cache.h b/src/mem/cache.h index c2c6f58..b91025c 100644 --- a/src/mem/cache.h +++ b/src/mem/cache.h @@ -87,6 +87,15 @@ char* mem_strdup(MemoryNamespaceName name, char* string); */ void* mem_clone(MemoryNamespaceName name, void* data, size_t size); +/** + * @brief Write formatted output into a dynamically allocated buffer managed by this cache, + * @param name + * @param format + * @param ... + * @return + */ +char* mem_asprintf(MemoryNamespaceName name, const char* format, ...); + void print_memory_statistics(); GArray* mem_new_g_array(MemoryNamespaceName name, guint element_size); diff --git a/src/set/set.c b/src/set/set.c index 0eb0f95..6039e0e 100644 --- a/src/set/set.c +++ b/src/set/set.c @@ -2868,6 +2868,7 @@ Module* create_set(AST_NODE_PTR currentNode) { rootModule->variables = variables; rootModule->imports = imports; rootModule->includes = includes; + rootModule->entry = NULL; DEBUG("created Module struct"); @@ -2922,11 +2923,24 @@ Module* create_set(AST_NODE_PTR currentNode) { Function* function = mem_alloc(MemoryNamespaceSet, sizeof(Function)); - if (createFunction(function, AST_get_node(currentNode, i)) + AST_NODE_PTR function_node = AST_get_node(currentNode, i); + if (createFunction(function, function_node) == SEMANTIC_ERROR) { return NULL; } + if (function_node->annotation.kind == AnnotationKindArray) { + if (AST_annotation_array_contains_flag(&function_node->annotation, "entry")) { + + if (rootModule->entry != NULL) { + print_diagnostic(&function_node->location, Error, "Multiple functions marked as entry points"); + return NULL; + } + + rootModule->entry = function->name; + } + } + g_hash_table_insert(rootModule->functions, function->name, function); DEBUG("created function successfully"); diff --git a/src/set/types.h b/src/set/types.h index a5a37e5..c836f37 100644 --- a/src/set/types.h +++ b/src/set/types.h @@ -602,6 +602,8 @@ typedef struct Module_t { // parent modules in descending order // root > submodule > current-module GArray* path; + // entry point symbol + char* entry; } Module; // .------------------------------------------------.