eolian: disallow ptr() on things that are already pointer-like

This disallows deeply nested pointers, you can only explicitly
ptr() on types that are strictly value types.

For a few cases where it was necessary to override this behavior,
you can use legacy(ptr(x)) as a temporary measure.
This commit is contained in:
Daniel Kolesa 2017-11-03 15:30:10 +01:00
parent e5d1cc731a
commit 0dbbb18171
8 changed files with 49 additions and 36 deletions

View File

@ -1,4 +1,4 @@
type @extern cairo_t: void_ptr; [[cairo_t type]] struct @extern cairo_t; [[cairo_t type]]
class Ector.Cairo.Surface (Efl.Object, Ector.Surface) class Ector.Cairo.Surface (Efl.Object, Ector.Surface)
{ {

View File

@ -169,7 +169,7 @@ class Elm.Calendar (Efl.Ui.Layout, Efl.Ui.Focus.Composition, Elm.Interface.Atspi
get { get {
} }
values { values {
weekdays: ptr(string); [[Array of seven strings to be used as weekday names. weekdays: legacy(ptr(string)); [[Array of seven strings to be used as weekday names.
Warning: It must have 7 elements, or it will access invalid memory. Warning: It must have 7 elements, or it will access invalid memory.
Warning: The strings must be $null terminated ('@\0').]] Warning: The strings must be $null terminated ('@\0').]]
} }

View File

@ -107,7 +107,7 @@ class Elm.Dayselector (Efl.Ui.Layout)
*/ */
params { params {
@in weekdays: ptr(string) @nullable; [[Array of seven strings to be used as weekday names. @in weekdays: legacy(ptr(string)) @nullable; [[Array of seven strings to be used as weekday names.
Warning: It must have 7 elements, or it will access invalid memory. Warning: It must have 7 elements, or it will access invalid memory.
Warning: The strings must be NULL terminated ('@\0').]] Warning: The strings must be NULL terminated ('@\0').]]
} }

View File

@ -431,7 +431,7 @@ class Elm.Map (Elm.Widget, Elm.Interface_Scrollable,
At least available sources of name type are "Nominatim". At least available sources of name type are "Nominatim".
]] ]]
return: ptr(string); [[The char pointer array of source names.]] return: legacy(ptr(string)); [[The char pointer array of source names.]]
params { params {
@in type: Elm.Map.Source_Type; [[Source type.]] @in type: Elm.Map.Source_Type; [[Source type.]]
} }

View File

@ -67,18 +67,6 @@ database_enum_add(Eolian_Typedecl *tp)
database_decl_add(tp->full_name, EOLIAN_DECL_ENUM, tp->base.file, tp); database_decl_add(tp->full_name, EOLIAN_DECL_ENUM, tp->base.file, tp);
} }
static const Eina_Bool _ownable_types[] = {
EINA_FALSE, /* unknown */
EINA_FALSE, /* void */
EINA_FALSE, /* regular */
EINA_TRUE, /* complex */
EINA_TRUE, /* pointer */
EINA_TRUE, /* class */
EINA_TRUE, /* static array */
EINA_TRUE, /* terminated array */
EINA_FALSE /* undefined */
};
Eina_Bool Eina_Bool
database_type_is_ownable(const Eolian_Type *tp) database_type_is_ownable(const Eolian_Type *tp)
{ {
@ -101,7 +89,7 @@ database_type_is_ownable(const Eolian_Type *tp)
} }
return (ct[strlen(ct) - 1] == '*'); return (ct[strlen(ct) - 1] == '*');
} }
return _ownable_types[tp->type]; return (tp->type == EOLIAN_TYPE_CLASS);
} }
static void static void

View File

@ -172,6 +172,17 @@ _validate_type(Eolian_Type *tp)
return _obj_error(&tp->base, buf); return _obj_error(&tp->base, buf);
} }
if (tp->is_ptr && !tp->legacy)
{
tp->is_ptr = EINA_FALSE;
Eina_Bool still_ownable = database_type_is_ownable(tp);
tp->is_ptr = EINA_TRUE;
if (still_ownable)
{
return _obj_error(&tp->base, "cannot take a pointer to pointer type");
}
}
switch (tp->type) switch (tp->type)
{ {
case EOLIAN_TYPE_VOID: case EOLIAN_TYPE_VOID:

View File

@ -456,14 +456,14 @@ parse_expr(Eo_Lexer *ls)
return parse_expr_bin(ls, 1); return parse_expr_bin(ls, 1);
} }
static Eolian_Type *parse_type_void(Eo_Lexer *ls, Eina_Bool allow_ref); static Eolian_Type *parse_type_void(Eo_Lexer *ls);
static Eolian_Type * static Eolian_Type *
parse_type(Eo_Lexer *ls, Eina_Bool allow_ref) parse_type(Eo_Lexer *ls)
{ {
Eolian_Type *ret; Eolian_Type *ret;
eo_lexer_context_push(ls); eo_lexer_context_push(ls);
ret = parse_type_void(ls, allow_ref); ret = parse_type_void(ls);
if (ret->type == EOLIAN_TYPE_VOID) if (ret->type == EOLIAN_TYPE_VOID)
{ {
eo_lexer_context_restore(ls); eo_lexer_context_restore(ls);
@ -512,7 +512,7 @@ parse_struct(Eo_Lexer *ls, const char *name, Eina_Bool is_extern,
def->field_list = eina_list_append(def->field_list, fdef); def->field_list = eina_list_append(def->field_list, fdef);
eo_lexer_get(ls); eo_lexer_get(ls);
check_next(ls, ':'); check_next(ls, ':');
tp = parse_type(ls, EINA_TRUE); tp = parse_type(ls);
FILL_BASE(fdef->base, ls, fline, fcol); FILL_BASE(fdef->base, ls, fline, fcol);
fdef->type = tp; fdef->type = tp;
fdef->name = eina_stringshare_ref(fname); fdef->name = eina_stringshare_ref(fname);
@ -687,7 +687,7 @@ _parse_dep(Eo_Lexer *ls, const char *fname, const char *name)
} }
static Eolian_Type * static Eolian_Type *
parse_type_void(Eo_Lexer *ls, Eina_Bool allow_ref) parse_type_void(Eo_Lexer *ls)
{ {
Eolian_Type *def; Eolian_Type *def;
Eina_Strbuf *buf; Eina_Strbuf *buf;
@ -701,7 +701,7 @@ parse_type_void(Eo_Lexer *ls, Eina_Bool allow_ref)
pline = ls->line_number; pline = ls->line_number;
pcol = ls->column; pcol = ls->column;
check_next(ls, '('); check_next(ls, '(');
def = parse_type_void(ls, allow_ref); def = parse_type_void(ls);
FILL_BASE(def->base, ls, line, col); FILL_BASE(def->base, ls, line, col);
def->is_const = EINA_TRUE; def->is_const = EINA_TRUE;
check_match(ls, ')', '(', pline, pcol); check_match(ls, ')', '(', pline, pcol);
@ -714,12 +714,25 @@ parse_type_void(Eo_Lexer *ls, Eina_Bool allow_ref)
pline = ls->line_number; pline = ls->line_number;
pcol = ls->column; pcol = ls->column;
check_next(ls, '('); check_next(ls, '(');
def = parse_type_void(ls, EINA_FALSE); def = parse_type_void(ls);
FILL_BASE(def->base, ls, line, col); FILL_BASE(def->base, ls, line, col);
def->is_ptr = EINA_TRUE; def->is_ptr = EINA_TRUE;
check_match(ls, ')', '(', pline, pcol); check_match(ls, ')', '(', pline, pcol);
return def; return def;
} }
case KW_legacy:
{
int pline, pcol;
eo_lexer_get(ls);
pline = ls->line_number;
pcol = ls->column;
check_next(ls, '(');
def = parse_type_void(ls);
FILL_BASE(def->base, ls, line, col);
def->legacy = EINA_TRUE;
check_match(ls, ')', '(', pline, pcol);
return def;
}
case KW_free: case KW_free:
{ {
int pline, pcolumn; int pline, pcolumn;
@ -727,7 +740,7 @@ parse_type_void(Eo_Lexer *ls, Eina_Bool allow_ref)
pline = ls->line_number; pline = ls->line_number;
pcolumn = ls->column; pcolumn = ls->column;
check_next(ls, '('); check_next(ls, '(');
def = parse_type_void(ls, allow_ref); def = parse_type_void(ls);
check_next(ls, ','); check_next(ls, ',');
check(ls, TOK_VALUE); check(ls, TOK_VALUE);
def->freefunc = eina_stringshare_ref(ls->t.value.s); def->freefunc = eina_stringshare_ref(ls->t.value.s);
@ -768,23 +781,23 @@ parse_type_void(Eo_Lexer *ls, Eina_Bool allow_ref)
int bline = ls->line_number, bcol = ls->column; int bline = ls->line_number, bcol = ls->column;
check_next(ls, '<'); check_next(ls, '<');
if (tpid == KW_future) if (tpid == KW_future)
def->base_type = parse_type_void(ls, EINA_FALSE); def->base_type = parse_type_void(ls);
else else
def->base_type = parse_type(ls, EINA_FALSE); def->base_type = parse_type(ls);
pop_type(ls); pop_type(ls);
if ((def->base_type->owned = (ls->t.kw == KW_at_owned))) if ((def->base_type->owned = (ls->t.kw == KW_at_owned)))
eo_lexer_get(ls); eo_lexer_get(ls);
if (tpid == KW_hash) if (tpid == KW_hash)
{ {
check_next(ls, ','); check_next(ls, ',');
def->base_type->next_type = parse_type(ls, EINA_FALSE); def->base_type->next_type = parse_type(ls);
pop_type(ls); pop_type(ls);
if ((def->base_type->next_type->owned = (ls->t.kw == KW_at_owned))) if ((def->base_type->next_type->owned = (ls->t.kw == KW_at_owned)))
eo_lexer_get(ls); eo_lexer_get(ls);
} }
else if((tpid == KW_future) && test_next(ls, ',')) else if((tpid == KW_future) && test_next(ls, ','))
{ {
def->base_type->next_type = parse_type_void(ls, EINA_FALSE); def->base_type->next_type = parse_type_void(ls);
pop_type(ls); pop_type(ls);
} }
check_match(ls, '>', '<', bline, bcol); check_match(ls, '>', '<', bline, bcol);
@ -854,7 +867,7 @@ parse_typedef(Eo_Lexer *ls)
} }
eo_lexer_context_pop(ls); eo_lexer_context_pop(ls);
check_next(ls, ':'); check_next(ls, ':');
def->base_type = parse_type(ls, EINA_FALSE); def->base_type = parse_type(ls);
pop_type(ls); pop_type(ls);
check_next(ls, ';'); check_next(ls, ';');
FILL_DOC(ls, def, doc); FILL_DOC(ls, def, doc);
@ -890,7 +903,7 @@ parse_variable(Eo_Lexer *ls, Eina_Bool global)
} }
eo_lexer_context_pop(ls); eo_lexer_context_pop(ls);
check_next(ls, ':'); check_next(ls, ':');
def->base_type = parse_type(ls, EINA_FALSE); def->base_type = parse_type(ls);
pop_type(ls); pop_type(ls);
/* constants are required to have a value */ /* constants are required to have a value */
if (!global) if (!global)
@ -926,9 +939,9 @@ parse_return(Eo_Lexer *ls, Eo_Ret_Def *ret, Eina_Bool allow_void,
eo_lexer_get(ls); eo_lexer_get(ls);
check_next(ls, ':'); check_next(ls, ':');
if (allow_void) if (allow_void)
ret->type = parse_type_void(ls, EINA_TRUE); ret->type = parse_type_void(ls);
else else
ret->type = parse_type(ls, EINA_TRUE); ret->type = parse_type(ls);
ret->doc = NULL; ret->doc = NULL;
ret->default_ret_val = NULL; ret->default_ret_val = NULL;
ret->warn_unused = EINA_FALSE; ret->warn_unused = EINA_FALSE;
@ -995,9 +1008,9 @@ parse_param(Eo_Lexer *ls, Eina_List **params, Eina_Bool allow_inout,
eo_lexer_get(ls); eo_lexer_get(ls);
check_next(ls, ':'); check_next(ls, ':');
if (par->param_dir == EOLIAN_OUT_PARAM || par->param_dir == EOLIAN_INOUT_PARAM) if (par->param_dir == EOLIAN_OUT_PARAM || par->param_dir == EOLIAN_INOUT_PARAM)
par->type = parse_type_void(ls, EINA_TRUE); par->type = parse_type_void(ls);
else else
par->type = parse_type(ls, EINA_TRUE); par->type = parse_type(ls);
pop_type(ls); pop_type(ls);
if ((is_vals || (par->param_dir == EOLIAN_OUT_PARAM)) && (ls->t.token == '(')) if ((is_vals || (par->param_dir == EOLIAN_OUT_PARAM)) && (ls->t.token == '('))
{ {
@ -1801,7 +1814,7 @@ end:
if (ls->t.token == ':') if (ls->t.token == ':')
{ {
eo_lexer_get(ls); eo_lexer_get(ls);
ev->type = parse_type(ls, EINA_TRUE); ev->type = parse_type(ls);
ev->type->owned = has_owned; ev->type->owned = has_owned;
pop_type(ls); pop_type(ls);
} }

View File

@ -177,6 +177,7 @@ struct _Eolian_Type
Eina_Bool is_const :1; Eina_Bool is_const :1;
Eina_Bool is_ptr :1; Eina_Bool is_ptr :1;
Eina_Bool owned :1; Eina_Bool owned :1;
Eina_Bool legacy :1;
}; };
struct _Eolian_Typedecl struct _Eolian_Typedecl