mirror of
https://github.com/c3lang/c3c.git
synced 2026-02-27 12:01:16 +00:00
Updated module visibility import visibility. Fixes to @local
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
module std::core::mem::allocator;
|
||||
|
||||
struct DynamicArenaPage @local
|
||||
struct DynamicArenaPage
|
||||
{
|
||||
void* memory;
|
||||
void* prev_arena;
|
||||
|
||||
@@ -496,8 +496,8 @@ fn usz! Formatter.vprintf(Formatter* this, String format, variant[] variants)
|
||||
return this.idx;
|
||||
}
|
||||
|
||||
typedef StringFunctionMap = HashMap<typeid, ToStringFunction> @private;
|
||||
typedef FormatterFunctionMap = HashMap<typeid, ToFormatFunction> @private;
|
||||
typedef StringFunctionMap @private = HashMap<typeid, ToStringFunction>;
|
||||
typedef FormatterFunctionMap @private = HashMap<typeid, ToFormatFunction>;
|
||||
|
||||
FormatterFunctionMap toformat_functions @private;
|
||||
StringFunctionMap tostring_functions @private;
|
||||
|
||||
@@ -858,7 +858,7 @@ Module *global_context_find_module(const char *name)
|
||||
return htable_get(&global_context.modules, (void *)name);
|
||||
}
|
||||
|
||||
Module *compiler_find_or_create_module(Path *module_name, const char **parameters, bool is_private)
|
||||
Module *compiler_find_or_create_module(Path *module_name, const char **parameters)
|
||||
{
|
||||
Module *module = global_context_find_module(module_name->module);
|
||||
if (module) return module;
|
||||
@@ -870,7 +870,6 @@ Module *compiler_find_or_create_module(Path *module_name, const char **parameter
|
||||
module->stage = ANALYSIS_NOT_BEGUN;
|
||||
module->parameters = parameters;
|
||||
module->is_generic = vec_size(parameters) > 0;
|
||||
module->is_private = is_private;
|
||||
htable_init(&module->symbols, 0x10000);
|
||||
htable_set(&global_context.modules, (void *)module_name->module, module);
|
||||
if (parameters)
|
||||
|
||||
@@ -397,7 +397,7 @@ typedef struct
|
||||
typedef struct
|
||||
{
|
||||
Path *path;
|
||||
bool private;
|
||||
bool import_private_as_public;
|
||||
Module *module;
|
||||
} ImportDecl;
|
||||
|
||||
@@ -1484,7 +1484,6 @@ typedef struct Module_
|
||||
bool is_c_library : 1;
|
||||
bool is_exported : 1;
|
||||
bool is_generic : 1;
|
||||
bool is_private : 1;
|
||||
bool no_extprefix : 1;
|
||||
AnalysisStage stage : 6;
|
||||
|
||||
@@ -1580,6 +1579,7 @@ struct CompilationUnit_
|
||||
Decl **enums;
|
||||
Decl **attributes;
|
||||
Decl **faulttypes;
|
||||
Visibility default_visibility;
|
||||
struct
|
||||
{
|
||||
// Not properly implemented
|
||||
@@ -2088,7 +2088,7 @@ void global_context_add_type(Type *type);
|
||||
void global_context_add_decl(Decl *type_decl);
|
||||
void global_context_add_generic_decl(Decl *decl);
|
||||
|
||||
Module *compiler_find_or_create_module(Path *module_name, const char **parameters, bool is_private);
|
||||
Module *compiler_find_or_create_module(Path *module_name, const char **parameters);
|
||||
Module *global_context_find_module(const char *name);
|
||||
const char *get_object_extension(void);
|
||||
|
||||
@@ -2098,7 +2098,7 @@ void unit_register_external_symbol(CompilationUnit *unit, Decl *decl);
|
||||
|
||||
bool unit_add_import(CompilationUnit *unit, Path *path, bool private_import);
|
||||
bool context_set_module_from_filename(ParseContext *context);
|
||||
bool context_set_module(ParseContext *context, Path *path, const char **generic_parameters, bool is_private);
|
||||
bool context_set_module(ParseContext *context, Path *path, const char **generic_parameters);
|
||||
|
||||
// --- Decl functions
|
||||
|
||||
|
||||
@@ -14,12 +14,12 @@ CompilationUnit *unit_create(File *file)
|
||||
}
|
||||
|
||||
|
||||
static inline bool create_module_or_check_name(CompilationUnit *unit, Path *module_name, const char **parameters, bool is_private)
|
||||
static inline bool create_module_or_check_name(CompilationUnit *unit, Path *module_name, const char **parameters)
|
||||
{
|
||||
Module *module = unit->module;
|
||||
if (!module)
|
||||
{
|
||||
module = unit->module = compiler_find_or_create_module(module_name, parameters, is_private);
|
||||
module = unit->module = compiler_find_or_create_module(module_name, parameters);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -33,19 +33,6 @@ static inline bool create_module_or_check_name(CompilationUnit *unit, Path *modu
|
||||
}
|
||||
}
|
||||
|
||||
if (module->is_private != is_private)
|
||||
{
|
||||
if (is_private)
|
||||
{
|
||||
SEMA_ERROR(module_name, "The module is declared as private here, but was declared as public elsewhere.");
|
||||
}
|
||||
else
|
||||
{
|
||||
SEMA_ERROR(module_name, "The module is declared as public here, but was declared as private elsewhere.");
|
||||
}
|
||||
return false;
|
||||
|
||||
}
|
||||
vec_add(module->units, unit);
|
||||
return true;
|
||||
}
|
||||
@@ -104,10 +91,10 @@ bool context_set_module_from_filename(ParseContext *context)
|
||||
path->span = INVALID_SPAN;
|
||||
path->module = module_name;
|
||||
path->len = scratch_buffer.len;
|
||||
return create_module_or_check_name(context->unit, path, NULL, true);
|
||||
return create_module_or_check_name(context->unit, path, NULL);
|
||||
}
|
||||
|
||||
bool context_set_module(ParseContext *context, Path *path, const char **generic_parameters, bool is_private)
|
||||
bool context_set_module(ParseContext *context, Path *path, const char **generic_parameters)
|
||||
{
|
||||
// Note that we allow the illegal name for now, to be able to parse further.
|
||||
if (!str_has_no_uppercase(path->module))
|
||||
@@ -116,7 +103,7 @@ bool context_set_module(ParseContext *context, Path *path, const char **generic_
|
||||
return false;
|
||||
}
|
||||
|
||||
return create_module_or_check_name(context->unit, path, generic_parameters, is_private);
|
||||
return create_module_or_check_name(context->unit, path, generic_parameters);
|
||||
}
|
||||
|
||||
|
||||
@@ -283,7 +270,10 @@ void unit_register_global_decl(CompilationUnit *unit, Decl *decl)
|
||||
|
||||
Decl *old;
|
||||
if ((old = htable_set(&unit->local_symbols, (void*)decl->name, decl))) goto ERR;
|
||||
if ((old = htable_set(&unit->module->symbols, (void*)decl->name, decl))) goto ERR;
|
||||
if (decl->visibility < VISIBLE_LOCAL)
|
||||
{
|
||||
if ((old = htable_set(&unit->module->symbols, (void*)decl->name, decl))) goto ERR;
|
||||
}
|
||||
return;
|
||||
ERR:
|
||||
assert(decl != old);
|
||||
@@ -306,7 +296,7 @@ bool unit_add_import(CompilationUnit *unit, Path *path, bool private_import)
|
||||
import->span = path->span;
|
||||
import->decl_kind = DECL_IMPORT;
|
||||
import->import.path = path;
|
||||
import->import.private = private_import;
|
||||
import->import.import_private_as_public = private_import;
|
||||
|
||||
vec_add(unit->imports, import);
|
||||
DEBUG_LOG("Added import %s", path->module);
|
||||
|
||||
@@ -782,6 +782,7 @@ typedef enum
|
||||
ATTRIBUTE_PACKED,
|
||||
ATTRIBUTE_PRIORITY,
|
||||
ATTRIBUTE_PRIVATE,
|
||||
ATTRIBUTE_PUBLIC,
|
||||
ATTRIBUTE_PURE,
|
||||
ATTRIBUTE_REFLECT,
|
||||
ATTRIBUTE_SECTION,
|
||||
|
||||
@@ -1123,7 +1123,7 @@ static void llvm_gen_test_main(GenContext *c)
|
||||
INLINE GenContext *llvm_gen_tests(Module** modules, unsigned module_count, LLVMContextRef shared_context)
|
||||
{
|
||||
Path *test_path = path_create_from_string("$test", 5, INVALID_SPAN);
|
||||
Module *test_module = compiler_find_or_create_module(test_path, NULL, false);
|
||||
Module *test_module = compiler_find_or_create_module(test_path, NULL);
|
||||
|
||||
GenContext *c = cmalloc(sizeof(GenContext));
|
||||
active_target.debug_info = DEBUG_INFO_NONE;
|
||||
|
||||
@@ -2,11 +2,12 @@
|
||||
#include "parser_internal.h"
|
||||
|
||||
|
||||
static Decl *parse_const_declaration(ParseContext *c);
|
||||
static Decl *parse_const_declaration(ParseContext *c, bool is_global);
|
||||
static inline Decl *parse_func_definition(ParseContext *c, AstId docs, bool is_interface);
|
||||
static inline bool parse_bitstruct_body(ParseContext *c, Decl *decl);
|
||||
static inline Decl *parse_static_top_level(ParseContext *c);
|
||||
static Decl *parse_include(ParseContext *c);
|
||||
static bool parse_attributes_for_global(ParseContext *c, Decl *decl);
|
||||
|
||||
#define DECL_VAR_NEW(type__, var__) decl_new_var(symstr(c), c->span, type__, var__);
|
||||
|
||||
@@ -310,12 +311,10 @@ static inline bool parse_optional_module_params(ParseContext *c, const char ***t
|
||||
|
||||
}
|
||||
/**
|
||||
* module ::= MODULE module_path ('<' module_params '>')? EOS
|
||||
* module ::= MODULE module_path ('<' module_params '>')? (@public|@private|@local)? EOS
|
||||
*/
|
||||
bool parse_module(ParseContext *c, AstId docs)
|
||||
{
|
||||
bool is_private = try_consume(c, TOKEN_PRIVATE);
|
||||
|
||||
if (tok_is(c, TOKEN_STRING))
|
||||
{
|
||||
SEMA_ERROR_HERE("'module' should be followed by a plain identifier, not a string. Did you accidentally put the module name between \"\"?");
|
||||
@@ -348,7 +347,7 @@ bool parse_module(ParseContext *c, AstId docs)
|
||||
path->len = (unsigned)strlen("#invalid");
|
||||
path->module = "#invalid";
|
||||
path->span = INVALID_SPAN;
|
||||
context_set_module(c, path, NULL, false);
|
||||
context_set_module(c, path, NULL);
|
||||
recover_top_level(c);
|
||||
return false;
|
||||
}
|
||||
@@ -357,7 +356,7 @@ bool parse_module(ParseContext *c, AstId docs)
|
||||
const char **generic_parameters = NULL;
|
||||
if (!parse_optional_module_params(c, &generic_parameters))
|
||||
{
|
||||
if (!context_set_module(c, path, NULL, is_private)) return false;
|
||||
if (!context_set_module(c, path, NULL)) return false;
|
||||
recover_top_level(c);
|
||||
if (docs)
|
||||
{
|
||||
@@ -366,7 +365,7 @@ bool parse_module(ParseContext *c, AstId docs)
|
||||
}
|
||||
return true;
|
||||
}
|
||||
if (!context_set_module(c, path, generic_parameters, is_private)) return false;
|
||||
if (!context_set_module(c, path, generic_parameters)) return false;
|
||||
if (docs)
|
||||
{
|
||||
AstId old_docs = c->unit->module->docs;
|
||||
@@ -380,7 +379,15 @@ bool parse_module(ParseContext *c, AstId docs)
|
||||
c->unit->module->docs = docs;
|
||||
}
|
||||
}
|
||||
|
||||
Visibility visibility = VISIBLE_PUBLIC;
|
||||
Attr** attrs = NULL;
|
||||
if (!parse_attributes(c, &attrs, &visibility)) return false;
|
||||
if (attrs)
|
||||
{
|
||||
sema_error_at(attrs[0]->span, "Unexpected '%s' after module name - only @public, @private and @local is permitted here.", attrs[0]->name);
|
||||
return false;
|
||||
}
|
||||
c->unit->default_visibility = visibility;
|
||||
CONSUME_EOS_OR_RET(false);
|
||||
return true;
|
||||
}
|
||||
@@ -779,7 +786,7 @@ TypeInfo *parse_optional_type(ParseContext *c)
|
||||
* @param type
|
||||
* @return
|
||||
*/
|
||||
Decl *parse_decl_after_type(ParseContext *c, TypeInfo *type)
|
||||
Decl *parse_local_decl_after_type(ParseContext *c, TypeInfo *type)
|
||||
{
|
||||
if (tok_is(c, TOKEN_LPAREN))
|
||||
{
|
||||
@@ -803,7 +810,7 @@ Decl *parse_decl_after_type(ParseContext *c, TypeInfo *type)
|
||||
Decl *decl = DECL_VAR_NEW(type, VARDECL_LOCAL);
|
||||
advance(c);
|
||||
|
||||
if (!parse_attributes(c, &decl->attributes, decl)) return poisoned_decl;
|
||||
if (!parse_attributes(c, &decl->attributes, NULL)) return poisoned_decl;
|
||||
if (tok_is(c, TOKEN_EQ))
|
||||
{
|
||||
if (!decl)
|
||||
@@ -826,7 +833,7 @@ Decl *parse_local_decl(ParseContext *c)
|
||||
{
|
||||
if (tok_is(c, TOKEN_CONST))
|
||||
{
|
||||
ASSIGN_DECL_OR_RET(Decl *decl, parse_const_declaration(c), poisoned_decl);
|
||||
ASSIGN_DECL_OR_RET(Decl *decl, parse_const_declaration(c, false), poisoned_decl);
|
||||
decl->visibility = VISIBLE_LOCAL;
|
||||
return decl;
|
||||
}
|
||||
@@ -836,7 +843,7 @@ Decl *parse_local_decl(ParseContext *c)
|
||||
|
||||
ASSIGN_TYPE_OR_RET(TypeInfo *type, parse_optional_type(c), poisoned_decl);
|
||||
|
||||
ASSIGN_DECL_OR_RET(Decl * decl, parse_decl_after_type(c, type), poisoned_decl);
|
||||
ASSIGN_DECL_OR_RET(Decl * decl, parse_local_decl_after_type(c, type), poisoned_decl);
|
||||
if (type->optional && decl->var.unwrap)
|
||||
{
|
||||
SEMA_ERROR(decl, "You cannot use unwrap with an optional variable.");
|
||||
@@ -858,7 +865,7 @@ Expr *parse_decl_or_expr(ParseContext *c, Decl **decl_ref)
|
||||
TypeInfo *type_info;
|
||||
Expr *expr = parse_expr(c);
|
||||
if (expr->expr_kind != EXPR_TYPEINFO) return expr;
|
||||
ASSIGN_DECL_OR_RET(*decl_ref, parse_decl_after_type(c, expr->type_expr), poisoned_expr);
|
||||
ASSIGN_DECL_OR_RET(*decl_ref, parse_local_decl_after_type(c, expr->type_expr), poisoned_expr);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -868,7 +875,7 @@ Expr *parse_decl_or_expr(ParseContext *c, Decl **decl_ref)
|
||||
* : 'const' type? IDENT '=' const_expr
|
||||
* ;
|
||||
*/
|
||||
static Decl *parse_const_declaration(ParseContext *c)
|
||||
static Decl *parse_const_declaration(ParseContext *c, bool is_global)
|
||||
{
|
||||
advance_and_verify(c, TOKEN_CONST);
|
||||
|
||||
@@ -882,7 +889,9 @@ static Decl *parse_const_declaration(ParseContext *c)
|
||||
|
||||
if (!consume_const_name(c, "const")) return poisoned_decl;
|
||||
|
||||
if (!parse_attributes(c, &decl->attributes, decl)) return poisoned_decl;
|
||||
Visibility visibility = is_global ? c->unit->default_visibility : VISIBLE_LOCAL;
|
||||
if (!parse_attributes(c, &decl->attributes, is_global ? &visibility : NULL)) return poisoned_decl;
|
||||
decl->visibility = visibility;
|
||||
|
||||
CONSUME_OR_RET(TOKEN_EQ, poisoned_decl);
|
||||
|
||||
@@ -1020,6 +1029,15 @@ bool parse_attribute(ParseContext *c, Attr **attribute_ref)
|
||||
*attribute_ref = attr;
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool parse_attributes_for_global(ParseContext *c, Decl *decl)
|
||||
{
|
||||
Visibility visibility = c->unit->default_visibility;
|
||||
if (!parse_attributes(c, &decl->attributes, &visibility)) return false;
|
||||
decl->visibility = visibility;
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* attribute_list
|
||||
* : attribute
|
||||
@@ -1031,42 +1049,41 @@ bool parse_attribute(ParseContext *c, Attr **attribute_ref)
|
||||
*
|
||||
* @return true if parsing succeeded, false if recovery is needed
|
||||
*/
|
||||
bool parse_attributes(ParseContext *c, Attr ***attributes_ref, Decl *owner)
|
||||
bool parse_attributes(ParseContext *c, Attr ***attributes_ref, Visibility *visibility_ref)
|
||||
{
|
||||
Visibility visibility = -1;
|
||||
while (1)
|
||||
{
|
||||
Attr *attr;
|
||||
if (!parse_attribute(c, &attr)) return false;
|
||||
if (!attr) return true;
|
||||
const char *name = attr->name;
|
||||
Visibility parsed_visibility = -1;
|
||||
if (name == attribute_list[ATTRIBUTE_PRIVATE])
|
||||
{
|
||||
if (!owner)
|
||||
{
|
||||
SEMA_ERROR(attr, "'%s' cannot be used here.");
|
||||
return false;
|
||||
}
|
||||
if (owner->visibility != VISIBLE_PUBLIC)
|
||||
{
|
||||
SEMA_ERROR(attr, "Only a single visibility attribute may be added.");
|
||||
return false;
|
||||
}
|
||||
owner->visibility = VISIBLE_PRIVATE;
|
||||
continue;
|
||||
parsed_visibility = VISIBLE_PRIVATE;
|
||||
}
|
||||
if (name == attribute_list[ATTRIBUTE_LOCAL])
|
||||
else if (name == attribute_list[ATTRIBUTE_PUBLIC])
|
||||
{
|
||||
if (!owner)
|
||||
parsed_visibility = VISIBLE_PUBLIC;
|
||||
}
|
||||
else if (name == attribute_list[ATTRIBUTE_LOCAL])
|
||||
{
|
||||
parsed_visibility = VISIBLE_LOCAL;
|
||||
}
|
||||
if (parsed_visibility != -1)
|
||||
{
|
||||
if (!visibility_ref)
|
||||
{
|
||||
SEMA_ERROR(attr, "'%s' cannot be used here.");
|
||||
return false;
|
||||
}
|
||||
if (owner->visibility != VISIBLE_PUBLIC)
|
||||
if (visibility != -1)
|
||||
{
|
||||
SEMA_ERROR(attr, "Only a single visibility attribute may be added.");
|
||||
return false;
|
||||
}
|
||||
owner->visibility = VISIBLE_LOCAL;
|
||||
*visibility_ref = visibility = parsed_visibility;
|
||||
continue;
|
||||
}
|
||||
FOREACH_BEGIN(Attr *other_attr, *attributes_ref)
|
||||
@@ -1127,7 +1144,8 @@ static inline Decl *parse_global_declaration(ParseContext *c)
|
||||
// Add the last, or we miss it.
|
||||
if (decls) vec_add(decls, decl);
|
||||
|
||||
if (!parse_attributes(c, &decl->attributes, decl)) return poisoned_decl;
|
||||
if (!parse_attributes_for_global(c, decl)) return poisoned_decl;
|
||||
|
||||
if (try_consume(c, TOKEN_EQ))
|
||||
{
|
||||
if (decls)
|
||||
@@ -1607,10 +1625,7 @@ static inline Decl *parse_struct_declaration(ParseContext *c)
|
||||
|
||||
if (!consume_type_name(c, type_name)) return poisoned_decl;
|
||||
|
||||
if (!parse_attributes(c, &decl->attributes, decl))
|
||||
{
|
||||
return poisoned_decl;
|
||||
}
|
||||
if (!parse_attributes_for_global(c, decl)) return poisoned_decl;
|
||||
|
||||
if (!parse_struct_body(c, decl))
|
||||
{
|
||||
@@ -1676,15 +1691,9 @@ static inline Decl *parse_bitstruct_declaration(ParseContext *c)
|
||||
|
||||
ASSIGN_TYPE_OR_RET(decl->bitstruct.base_type, parse_type(c), poisoned_decl);
|
||||
|
||||
if (!parse_attributes(c, &decl->attributes, decl))
|
||||
{
|
||||
return poisoned_decl;
|
||||
}
|
||||
if (!parse_attributes_for_global(c, decl)) return poisoned_decl;
|
||||
|
||||
if (!parse_bitstruct_body(c, decl))
|
||||
{
|
||||
return poisoned_decl;
|
||||
}
|
||||
if (!parse_bitstruct_body(c, decl)) return poisoned_decl;
|
||||
|
||||
return decl;
|
||||
|
||||
@@ -1692,7 +1701,7 @@ static inline Decl *parse_bitstruct_declaration(ParseContext *c)
|
||||
|
||||
static inline Decl *parse_top_level_const_declaration(ParseContext *c)
|
||||
{
|
||||
ASSIGN_DECL_OR_RET(Decl * decl, parse_const_declaration(c), poisoned_decl);
|
||||
ASSIGN_DECL_OR_RET(Decl * decl, parse_const_declaration(c, true), poisoned_decl);
|
||||
CONSUME_EOS_OR_RET(poisoned_decl);
|
||||
return decl;
|
||||
}
|
||||
@@ -1792,7 +1801,9 @@ static inline Decl *parse_define_type(ParseContext *c)
|
||||
SEMA_ERROR_HERE("A type name was expected here.");
|
||||
return poisoned_decl;
|
||||
}
|
||||
if (!parse_attributes(c, &decl->attributes, decl)) return false;
|
||||
|
||||
if (!parse_attributes_for_global(c, decl)) return poisoned_decl;
|
||||
|
||||
CONSUME_OR_RET(TOKEN_EQ, poisoned_decl);
|
||||
bool distinct = false;
|
||||
if (tok_is(c, TOKEN_IDENT) && symstr(c) == kw_distinct)
|
||||
@@ -1833,7 +1844,6 @@ static inline Decl *parse_define_type(ParseContext *c)
|
||||
decl->define_decl.type_info = type_info;
|
||||
decl->define_decl.generic_params = params;
|
||||
RANGE_EXTEND_PREV(decl);
|
||||
if (!parse_attributes(c, &decl->attributes, decl)) return false;
|
||||
CONSUME_EOS_OR_RET(poisoned_decl);
|
||||
return decl;
|
||||
}
|
||||
@@ -1985,8 +1995,9 @@ static inline Decl *parse_define_attribute(ParseContext *c)
|
||||
CONSUME_OR_RET(TOKEN_RPAREN, poisoned_decl);
|
||||
}
|
||||
|
||||
if (!parse_attributes_for_global(c, decl)) return poisoned_decl;
|
||||
Attr **attributes = NULL;
|
||||
if (!parse_attributes(c, &decl->attributes, decl)) return poisoned_decl;
|
||||
|
||||
CONSUME_OR_RET(TOKEN_EQ, poisoned_decl);
|
||||
CONSUME_OR_RET(TOKEN_LBRACE, poisoned_decl);
|
||||
|
||||
@@ -2104,7 +2115,7 @@ static inline Decl *parse_macro_declaration(ParseContext *c, AstId docs)
|
||||
const char *block_parameter = NULL;
|
||||
if (!parse_macro_arguments(c, decl)) return poisoned_decl;
|
||||
|
||||
if (!parse_attributes(c, &decl->attributes, decl)) return poisoned_decl;
|
||||
if (!parse_attributes_for_global(c, decl)) return poisoned_decl;
|
||||
if (tok_is(c, TOKEN_IMPLIES))
|
||||
{
|
||||
ASSIGN_ASTID_OR_RET(decl->func_decl.body,
|
||||
@@ -2235,7 +2246,8 @@ static inline Decl *parse_enum_declaration(ParseContext *c, bool is_private)
|
||||
if (!parse_enum_spec(c, &type, &decl->enums.parameters)) return poisoned_decl;
|
||||
}
|
||||
|
||||
if (!parse_attributes(c, &decl->attributes, decl)) return poisoned_decl;
|
||||
if (!parse_attributes_for_global(c, decl)) return poisoned_decl;
|
||||
|
||||
Visibility visibility = decl->visibility;
|
||||
CONSUME_OR_RET(TOKEN_LBRACE, poisoned_decl);
|
||||
|
||||
@@ -2315,7 +2327,7 @@ static inline Decl *parse_func_definition(ParseContext *c, AstId docs, bool is_i
|
||||
return false;
|
||||
}
|
||||
if (!parse_fn_parameter_list(c, &(func->func_decl.signature), is_interface)) return poisoned_decl;
|
||||
if (!parse_attributes(c, &func->attributes, func)) return poisoned_decl;
|
||||
if (!parse_attributes_for_global(c, func)) return poisoned_decl;
|
||||
|
||||
// TODO remove
|
||||
is_interface = tok_is(c, TOKEN_EOS);
|
||||
@@ -2404,8 +2416,6 @@ static inline bool parse_import(ParseContext *c)
|
||||
{
|
||||
advance_and_verify(c, TOKEN_IMPORT);
|
||||
|
||||
bool private = try_consume(c, TOKEN_PRIVATE);
|
||||
|
||||
bool is_not_first = false;
|
||||
while (1)
|
||||
{
|
||||
@@ -2427,6 +2437,17 @@ static inline bool parse_import(ParseContext *c)
|
||||
is_not_first = true;
|
||||
Path *path = parse_module_path(c);
|
||||
if (!path) return false;
|
||||
bool private = false;
|
||||
if (tok_is(c, TOKEN_AT_IDENT))
|
||||
{
|
||||
if (symstr(c) != attribute_list[ATTRIBUTE_PUBLIC])
|
||||
{
|
||||
SEMA_ERROR_HERE("Only '@public' is a valid attribute here.");
|
||||
return false;
|
||||
}
|
||||
private = true;
|
||||
advance_and_verify(c, TOKEN_AT_IDENT);
|
||||
}
|
||||
unit_add_import(c->unit, path, private);
|
||||
if (tok_is(c, TOKEN_COLON) && peek(c) == TOKEN_IDENT)
|
||||
{
|
||||
|
||||
@@ -15,7 +15,7 @@ static Ast *parse_declaration_statment_after_type(ParseContext *c, TypeInfo *typ
|
||||
Ast *ast = ast_calloc();
|
||||
ast->span = type->span;
|
||||
ast->ast_kind = AST_DECLARE_STMT;
|
||||
ASSIGN_DECL_OR_RET(ast->declare_stmt, parse_decl_after_type(c, type), poisoned_ast);
|
||||
ASSIGN_DECL_OR_RET(ast->declare_stmt, parse_local_decl_after_type(c, type), poisoned_ast);
|
||||
|
||||
if (tok_is(c, TOKEN_EOS)) return ast;
|
||||
Decl *decl = ast->declare_stmt;
|
||||
@@ -43,7 +43,7 @@ static Ast *parse_declaration_statment_after_type(ParseContext *c, TypeInfo *typ
|
||||
Attr **attributes = NULL;
|
||||
while (try_consume(c, TOKEN_COMMA))
|
||||
{
|
||||
ASSIGN_DECL_OR_RET(decl, parse_decl_after_type(c, copy_type_info_single(type)), poisoned_ast);
|
||||
ASSIGN_DECL_OR_RET(decl, parse_local_decl_after_type(c, copy_type_info_single(type)), poisoned_ast);
|
||||
if (decl->var.init_expr)
|
||||
{
|
||||
SEMA_ERROR(decl->var.init_expr, "Multiple variable declarations cannot use initialization.");
|
||||
|
||||
@@ -48,12 +48,12 @@ Ast* parse_compound_stmt(ParseContext *c);
|
||||
Ast *parse_short_body(ParseContext *c, TypeInfoId return_type, bool require_eos);
|
||||
Ast *parse_jump_stmt_no_eos(ParseContext *c);
|
||||
bool parse_attribute(ParseContext *c, Attr **attribute_ref);
|
||||
bool parse_attributes(ParseContext *c, Attr ***attributes_ref, Decl *owner);
|
||||
bool parse_attributes(ParseContext *c, Attr ***attributes_ref, Visibility *visibility);
|
||||
|
||||
bool parse_switch_body(ParseContext *c, Ast ***cases, TokenType case_type, TokenType default_type);
|
||||
Expr *parse_ct_expression_list(ParseContext *c, bool allow_decl);
|
||||
Expr *parse_expression_list(ParseContext *c, bool allow_decls);
|
||||
Decl *parse_decl_after_type(ParseContext *c, TypeInfo *type);
|
||||
Decl *parse_local_decl_after_type(ParseContext *c, TypeInfo *type);
|
||||
Decl *parse_var_decl(ParseContext *c);
|
||||
|
||||
bool parse_parameters(ParseContext *c, Decl ***params_ref, Decl **body_params,
|
||||
|
||||
@@ -1502,6 +1502,11 @@ static bool sema_analyse_attribute(SemaContext *context, Decl *decl, Attr *attr,
|
||||
Expr *expr = args ? attr->exprs[0] : NULL;
|
||||
switch (type)
|
||||
{
|
||||
case ATTRIBUTE_PRIVATE:
|
||||
case ATTRIBUTE_PUBLIC:
|
||||
case ATTRIBUTE_LOCAL:
|
||||
// These are pseudo-attributes.
|
||||
UNREACHABLE;
|
||||
case ATTRIBUTE_WINMAIN:
|
||||
if (decl->name != kw_main)
|
||||
{
|
||||
@@ -1531,22 +1536,6 @@ static bool sema_analyse_attribute(SemaContext *context, Decl *decl, Attr *attr,
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case ATTRIBUTE_PRIVATE:
|
||||
if (decl->visibility != VISIBLE_PUBLIC)
|
||||
{
|
||||
SEMA_ERROR(decl, "Multiple visibility attributes cannot be combined.");
|
||||
return false;
|
||||
}
|
||||
decl->visibility = VISIBLE_PRIVATE;
|
||||
break;
|
||||
case ATTRIBUTE_LOCAL:
|
||||
if (decl->visibility != VISIBLE_PUBLIC)
|
||||
{
|
||||
SEMA_ERROR(decl, "Multiple visibility attributes cannot be combined.");
|
||||
return false;
|
||||
}
|
||||
decl->visibility = VISIBLE_LOCAL;
|
||||
break;
|
||||
case ATTRIBUTE_TEST:
|
||||
decl->func_decl.attr_test = true;
|
||||
break;
|
||||
@@ -2764,7 +2753,7 @@ static CompilationUnit *unit_copy(Module *module, CompilationUnit *unit)
|
||||
|
||||
static Module *module_instantiate_generic(Module *module, Path *path, Expr **params)
|
||||
{
|
||||
Module *new_module = compiler_find_or_create_module(path, NULL, module->is_private);
|
||||
Module *new_module = compiler_find_or_create_module(path, NULL);
|
||||
new_module->is_generic = false;
|
||||
CompilationUnit **units = module->units;
|
||||
VECEACH(units, i)
|
||||
|
||||
@@ -153,7 +153,7 @@ static Decl *sema_find_decl_in_imports(Decl **imports, NameResolve *name_resolve
|
||||
assert(found->visibility != VISIBLE_LOCAL);
|
||||
|
||||
// If we found something private but we don't import privately?
|
||||
if (found->visibility == VISIBLE_PRIVATE && !import->import.private && !decl)
|
||||
if (found->visibility == VISIBLE_PRIVATE && !import->import.import_private_as_public && !decl)
|
||||
{
|
||||
// Register this as a possible private decl.
|
||||
name_resolve->private_decl = found;
|
||||
@@ -704,7 +704,7 @@ Decl *sema_resolve_type_method(CompilationUnit *unit, Type *type, const char *me
|
||||
|
||||
Decl *new_found = sema_resolve_method_in_module(import->import.module, type, method_name,
|
||||
&private, &ambiguous,
|
||||
import->import.private
|
||||
import->import.import_private_as_public
|
||||
? METHOD_SEARCH_PRIVATE_IMPORTED
|
||||
: METHOD_SEARCH_IMPORTED);
|
||||
if (!new_found) continue;
|
||||
|
||||
@@ -52,7 +52,7 @@ void sema_analyse_pass_module_hierarchy(Module *module)
|
||||
// No match, so we create a synthetic module.
|
||||
Path *path = path_create_from_string(slice.ptr, slice.len, module->name->span);
|
||||
DEBUG_LOG("Creating parent module for %s: %s", module->name->module, path->module);
|
||||
Module *parent_module = compiler_find_or_create_module(path, NULL, false /* always public */);
|
||||
Module *parent_module = compiler_find_or_create_module(path, NULL);
|
||||
module->parent_module = parent_module;
|
||||
vec_add(parent_module->sub_modules, module);
|
||||
sema_analyze_stage(parent_module, ANALYSIS_MODULE_HIERARCHY);
|
||||
@@ -100,15 +100,7 @@ void sema_analysis_pass_process_imports(Module *module)
|
||||
continue;
|
||||
}
|
||||
|
||||
// 7. Importing private is not allowed.
|
||||
if (import_module->is_private && !import->import.private)
|
||||
{
|
||||
SEMA_ERROR(import, "Importing a private module is not allowed (unless 'import private' is used).");
|
||||
decl_poison(import);
|
||||
continue;
|
||||
}
|
||||
|
||||
// 8. Assign the module.
|
||||
// 7. Assign the module.
|
||||
DEBUG_LOG("* Import of %s.", path->module);
|
||||
import->import.module = import_module;
|
||||
}
|
||||
|
||||
@@ -294,7 +294,7 @@ void sema_analysis_run(void)
|
||||
core_path->module = kw_std__core;
|
||||
core_path->span = INVALID_SPAN;
|
||||
core_path->len = strlen(kw_std__core);
|
||||
global_context.core_module = compiler_find_or_create_module(core_path, NULL, false);
|
||||
global_context.core_module = compiler_find_or_create_module(core_path, NULL);
|
||||
|
||||
// We parse the generic modules, just by storing the decls.
|
||||
FOREACH_BEGIN(Module *module, global_context.generic_module_list)
|
||||
|
||||
@@ -315,6 +315,7 @@ void symtab_init(uint32_t capacity)
|
||||
attribute_list[ATTRIBUTE_PRIORITY] = KW_DEF("@priority");
|
||||
attribute_list[ATTRIBUTE_PRIVATE] = KW_DEF("@private");
|
||||
attribute_list[ATTRIBUTE_PURE] = kw_at_pure;
|
||||
attribute_list[ATTRIBUTE_PUBLIC] = KW_DEF("@public");
|
||||
attribute_list[ATTRIBUTE_REFLECT] = KW_DEF("@reflect");
|
||||
attribute_list[ATTRIBUTE_SECTION] = KW_DEF("@section");
|
||||
attribute_list[ATTRIBUTE_STDCALL] = KW_DEF("@stdcall");
|
||||
|
||||
@@ -7,7 +7,7 @@ macro @hello(Type thing) {
|
||||
|
||||
module bar;
|
||||
|
||||
import private foo;
|
||||
import foo @public;
|
||||
|
||||
define intHello = foo::@hello<int>; // #error: cannot be aliased
|
||||
define @intHello = foo::hello<int>; // #error: cannot use
|
||||
|
||||
@@ -7,7 +7,7 @@ macro @hello(Type thing) {
|
||||
|
||||
module bar;
|
||||
|
||||
import private foo;
|
||||
import foo @public;
|
||||
|
||||
define @intHello = foo::@hello<int>;
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@ fn void foo1() @private
|
||||
{}
|
||||
|
||||
module bar;
|
||||
import private foo;
|
||||
import foo @public;
|
||||
macro bar1()
|
||||
{
|
||||
foo::foo1();
|
||||
|
||||
@@ -15,7 +15,7 @@ fn int Bar.get2(Bar* f) => f.x;
|
||||
fn int Bar.get3(Bar* f) @local => f.x;
|
||||
|
||||
module abc;
|
||||
import private test;
|
||||
import test @public;
|
||||
|
||||
struct Bar
|
||||
{
|
||||
|
||||
@@ -1 +1 @@
|
||||
module private foo;
|
||||
module foo @private;
|
||||
@@ -9,15 +9,14 @@ fn void runBar()
|
||||
|
||||
// #file: file2.c3
|
||||
module baz;
|
||||
import private bar;
|
||||
import bar @public;
|
||||
|
||||
fn void visible()
|
||||
@private{
|
||||
fn void visible() @private
|
||||
{
|
||||
bar::barFunc();
|
||||
}
|
||||
|
||||
// #file: file3.c3
|
||||
module bar;
|
||||
|
||||
fn void barFunc()
|
||||
@private{}
|
||||
fn void barFunc() @private {}
|
||||
@@ -13,7 +13,7 @@ fn void test()
|
||||
}
|
||||
|
||||
module baz;
|
||||
import private foo;
|
||||
import foo @public;
|
||||
|
||||
fn void test()
|
||||
{
|
||||
|
||||
27
test/test_suite/visibility/private_import2.c3
Normal file
27
test/test_suite/visibility/private_import2.c3
Normal file
@@ -0,0 +1,27 @@
|
||||
module test;
|
||||
|
||||
fn void bar() @private
|
||||
{
|
||||
}
|
||||
fn void bar2() @local
|
||||
{
|
||||
}
|
||||
|
||||
module baz;
|
||||
import test @public;
|
||||
|
||||
fn void abc()
|
||||
{
|
||||
test::bar();
|
||||
test::bar2(); // #error: could not be found
|
||||
}
|
||||
|
||||
module baz2;
|
||||
|
||||
import test;
|
||||
|
||||
fn void abc()
|
||||
{
|
||||
test::bar(); // #error: not visible
|
||||
test::bar2(); // #error: could not be found
|
||||
}
|
||||
@@ -1,17 +0,0 @@
|
||||
module private foo;
|
||||
|
||||
fn void hidden()
|
||||
{
|
||||
}
|
||||
|
||||
module bar;
|
||||
import foo; // #error: Importing a private module is not allowed (unless 'import private' is used).
|
||||
|
||||
|
||||
module baz;
|
||||
import private foo;
|
||||
|
||||
fn void test()
|
||||
{
|
||||
foo::hidden();
|
||||
}
|
||||
@@ -9,7 +9,4 @@ fn void runBar()
|
||||
// #file: file2.c3
|
||||
module baz;
|
||||
|
||||
fn void visible()
|
||||
@private{
|
||||
|
||||
}
|
||||
fn void visible() @private {}
|
||||
Reference in New Issue
Block a user