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); 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 static void
_buf_add_suffix(Eina_Strbuf *buf, const char *suffix) _buf_add_suffix(Eina_Strbuf *buf, const char *suffix)
{ {
@ -77,16 +105,22 @@ _buf_add_suffix(Eina_Strbuf *buf, const char *suffix)
} }
void 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 if ((tp->type == EOLIAN_TYPE_COMPLEX
|| tp->type == EOLIAN_TYPE_COMPLEX
|| tp->type == EOLIAN_TYPE_VOID
|| tp->type == EOLIAN_TYPE_CLASS) || tp->type == EOLIAN_TYPE_CLASS)
&& tp->is_const) && tp->is_const)
{ {
eina_strbuf_append(buf, "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 if (tp->type == EOLIAN_TYPE_REGULAR
|| tp->type == EOLIAN_TYPE_COMPLEX || tp->type == EOLIAN_TYPE_COMPLEX
|| tp->type == EOLIAN_TYPE_CLASS) || tp->type == EOLIAN_TYPE_CLASS)
@ -111,9 +145,10 @@ database_type_to_str(const Eolian_Type *tp, Eina_Strbuf *buf, const char *name)
else else
{ {
/* handles arrays and pointers as they all serialize to pointers */ /* 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, "*"); _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) if (tp->type == EOLIAN_TYPE_COMPLEX || tp->type == EOLIAN_TYPE_CLASS)
_buf_add_suffix(buf, "*"); _buf_add_suffix(buf, "*");
@ -140,7 +175,7 @@ _stype_to_str(const Eolian_Typedecl *tp, Eina_Strbuf *buf)
eina_strbuf_append(buf, " { "); eina_strbuf_append(buf, " { ");
EINA_LIST_FOREACH(tp->field_list, l, sf) 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, "; ");
} }
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(); Eina_Strbuf *fulln = eina_strbuf_new();
_append_name(tp, fulln); _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); eina_strbuf_free(fulln);
} }

View File

@ -355,13 +355,13 @@ eolian_typedecl_is_extern(const Eolian_Typedecl *tp)
} }
EAPI Eina_Stringshare * 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_Stringshare *ret;
Eina_Strbuf *buf; Eina_Strbuf *buf;
EINA_SAFETY_ON_NULL_RETURN_VAL(tp, NULL); EINA_SAFETY_ON_NULL_RETURN_VAL(tp, NULL);
buf = eina_strbuf_new(); 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)); ret = eina_stringshare_add(eina_strbuf_string_get(buf));
eina_strbuf_free(buf); eina_strbuf_free(buf);
return ret; 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 static Eina_Bool
_type_is_terminatable(Eolian_Type *tp) _type_is_terminatable(Eolian_Type *tp)
{ {
if (_type_is_ownable(tp)) if (database_type_is_ownable(tp))
return EINA_TRUE; return EINA_TRUE;
if (tp->type == EOLIAN_TYPE_REGULAR) 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, '('); check_next(ls, '(');
eo_lexer_context_push(ls); eo_lexer_context_push(ls);
def = parse_type_void(ls, allow_ref, EINA_FALSE); 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_context_restore(ls);
eo_lexer_syntax_error(ls, "ownable type expected"); 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, '('); check_next(ls, '(');
eo_lexer_context_push(ls); eo_lexer_context_push(ls);
def = parse_type_void(ls, allow_ref, EINA_FALSE); 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_context_restore(ls);
eo_lexer_syntax_error(ls, "freeable type expected"); 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_type_del(Eolian_Type *tp);
void database_typedecl_del(Eolian_Typedecl *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); 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 */ /* expressions */
Eolian_Value database_expr_eval(const Eolian_Unit *unit, const Eolian_Expression *expr, Eolian_Expression_Mask mask); Eolian_Value database_expr_eval(const Eolian_Unit *unit, const Eolian_Expression *expr, Eolian_Expression_Mask mask);