eolian: implement proper return type serialization

This accounts for const so that you can't generate functions
that return const values, as that makes no sense.

@fix T5024
This commit is contained in:
Daniel Kolesa 2017-08-10 12:41:03 +02:00
parent e38418dd9d
commit 706de57b9f
4 changed files with 52 additions and 42 deletions

View File

@ -67,6 +67,34 @@ database_enum_add(Eolian_Typedecl *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
database_type_is_ownable(const Eolian_Type *tp)
{
if (tp->is_ptr)
return EINA_TRUE;
if (tp->type == EOLIAN_TYPE_REGULAR)
{
int kwid = eo_lexer_keyword_str_to_id(tp->name);
const char *ct = eo_lexer_get_c_type(kwid);
if (!ct)
return EINA_FALSE;
return (ct[strlen(ct) - 1] == '*');
}
return _ownable_types[tp->type];
}
static void
_buf_add_suffix(Eina_Strbuf *buf, const char *suffix)
{
@ -77,16 +105,22 @@ _buf_add_suffix(Eina_Strbuf *buf, const char *suffix)
}
void
database_type_to_str(const Eolian_Type *tp, Eina_Strbuf *buf, const char *name)
database_type_to_str(const Eolian_Type *tp, Eina_Strbuf *buf, const char *name,
Eolian_C_Type_Type ctype)
{
if ((tp->type == EOLIAN_TYPE_REGULAR
|| tp->type == EOLIAN_TYPE_COMPLEX
|| tp->type == EOLIAN_TYPE_VOID
if ((tp->type == EOLIAN_TYPE_COMPLEX
|| tp->type == EOLIAN_TYPE_CLASS)
&& tp->is_const)
{
eina_strbuf_append(buf, "const ");
}
if ((tp->type == EOLIAN_TYPE_REGULAR
|| tp->type == EOLIAN_TYPE_VOID)
&& tp->is_const
&& ((ctype != EOLIAN_C_TYPE_RETURN) || database_type_is_ownable(tp)))
{
eina_strbuf_append(buf, "const ");
}
if (tp->type == EOLIAN_TYPE_REGULAR
|| tp->type == EOLIAN_TYPE_COMPLEX
|| tp->type == EOLIAN_TYPE_CLASS)
@ -111,9 +145,10 @@ database_type_to_str(const Eolian_Type *tp, Eina_Strbuf *buf, const char *name)
else
{
/* handles arrays and pointers as they all serialize to pointers */
database_type_to_str(tp->base_type, buf, NULL);
database_type_to_str(tp->base_type, buf, NULL, EOLIAN_C_TYPE_DEFAULT);
_buf_add_suffix(buf, "*");
if (tp->is_const) eina_strbuf_append(buf, " const");
if (tp->is_const && (ctype != EOLIAN_C_TYPE_RETURN))
eina_strbuf_append(buf, " const");
}
if (tp->type == EOLIAN_TYPE_COMPLEX || tp->type == EOLIAN_TYPE_CLASS)
_buf_add_suffix(buf, "*");
@ -140,7 +175,7 @@ _stype_to_str(const Eolian_Typedecl *tp, Eina_Strbuf *buf)
eina_strbuf_append(buf, " { ");
EINA_LIST_FOREACH(tp->field_list, l, sf)
{
database_type_to_str(sf->type, buf, sf->name);
database_type_to_str(sf->type, buf, sf->name, EOLIAN_C_TYPE_DEFAULT);
eina_strbuf_append(buf, "; ");
}
eina_strbuf_append(buf, "}");
@ -212,7 +247,8 @@ _atype_to_str(const Eolian_Typedecl *tp, Eina_Strbuf *buf)
Eina_Strbuf *fulln = eina_strbuf_new();
_append_name(tp, fulln);
database_type_to_str(tp->base_type, buf, eina_strbuf_string_get(fulln));
database_type_to_str(tp->base_type, buf, eina_strbuf_string_get(fulln),
EOLIAN_C_TYPE_DEFAULT);
eina_strbuf_free(fulln);
}

View File

@ -355,13 +355,13 @@ eolian_typedecl_is_extern(const Eolian_Typedecl *tp)
}
EAPI Eina_Stringshare *
eolian_type_c_type_get(const Eolian_Type *tp, Eolian_C_Type_Type ctype EINA_UNUSED)
eolian_type_c_type_get(const Eolian_Type *tp, Eolian_C_Type_Type ctype)
{
Eina_Stringshare *ret;
Eina_Strbuf *buf;
EINA_SAFETY_ON_NULL_RETURN_VAL(tp, NULL);
buf = eina_strbuf_new();
database_type_to_str(tp, buf, NULL);
database_type_to_str(tp, buf, NULL, ctype);
ret = eina_stringshare_add(eina_strbuf_string_get(buf));
eina_strbuf_free(buf);
return ret;

View File

@ -684,38 +684,10 @@ _parse_dep(Eo_Lexer *ls, const char *fname, const char *name)
}
}
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 */
};
static Eina_Bool
_type_is_ownable(Eolian_Type *tp)
{
if (tp->is_ptr)
return EINA_TRUE;
if (tp->type == EOLIAN_TYPE_REGULAR)
{
int kwid = eo_lexer_keyword_str_to_id(tp->name);
const char *ct = eo_lexer_get_c_type(kwid);
if (!ct)
return EINA_FALSE;
return (ct[strlen(ct) - 1] == '*');
}
return _ownable_types[tp->type];
}
static Eina_Bool
_type_is_terminatable(Eolian_Type *tp)
{
if (_type_is_ownable(tp))
if (database_type_is_ownable(tp))
return EINA_TRUE;
if (tp->type == EOLIAN_TYPE_REGULAR)
{
@ -769,7 +741,7 @@ parse_type_void(Eo_Lexer *ls, Eina_Bool allow_ref, Eina_Bool allow_sarray)
check_next(ls, '(');
eo_lexer_context_push(ls);
def = parse_type_void(ls, allow_ref, EINA_FALSE);
if (!_type_is_ownable(def))
if (!database_type_is_ownable(def))
{
eo_lexer_context_restore(ls);
eo_lexer_syntax_error(ls, "ownable type expected");
@ -789,7 +761,7 @@ parse_type_void(Eo_Lexer *ls, Eina_Bool allow_ref, Eina_Bool allow_sarray)
check_next(ls, '(');
eo_lexer_context_push(ls);
def = parse_type_void(ls, allow_ref, EINA_FALSE);
if (!_type_is_ownable(def))
if (!database_type_is_ownable(def))
{
eo_lexer_context_restore(ls);
eo_lexer_syntax_error(ls, "freeable type expected");

View File

@ -312,9 +312,11 @@ void database_enum_add(Eolian_Typedecl *tp);
void database_type_del(Eolian_Type *tp);
void database_typedecl_del(Eolian_Typedecl *tp);
void database_type_to_str(const Eolian_Type *tp, Eina_Strbuf *buf, const char *name);
void database_type_to_str(const Eolian_Type *tp, Eina_Strbuf *buf, const char *name, Eolian_C_Type_Type ctype);
void database_typedecl_to_str(const Eolian_Unit *src, const Eolian_Typedecl *tp, Eina_Strbuf *buf);
Eina_Bool database_type_is_ownable(const Eolian_Type *tp);
/* expressions */
Eolian_Value database_expr_eval(const Eolian_Unit *unit, const Eolian_Expression *expr, Eolian_Expression_Mask mask);