eolian: merge REGULAR and COMPLEX types

This commit is contained in:
Daniel Kolesa 2017-09-22 17:46:02 +02:00
parent f36e5bd543
commit 4bae2a7385
9 changed files with 69 additions and 77 deletions

View File

@ -79,7 +79,6 @@ ffi.cdef [[
EOLIAN_TYPE_UNKNOWN_TYPE = 0, EOLIAN_TYPE_UNKNOWN_TYPE = 0,
EOLIAN_TYPE_VOID, EOLIAN_TYPE_VOID,
EOLIAN_TYPE_REGULAR, EOLIAN_TYPE_REGULAR,
EOLIAN_TYPE_COMPLEX,
EOLIAN_TYPE_CLASS, EOLIAN_TYPE_CLASS,
EOLIAN_TYPE_STATIC_ARRAY, EOLIAN_TYPE_STATIC_ARRAY,
EOLIAN_TYPE_TERMINATED_ARRAY, EOLIAN_TYPE_TERMINATED_ARRAY,
@ -504,11 +503,10 @@ M.type_type = {
UNKNOWN = 0, UNKNOWN = 0,
VOID = 1, VOID = 1,
REGULAR = 2, REGULAR = 2,
COMPLEX = 3, CLASS = 3,
CLASS = 4, STATIC_ARRAY = 4,
STATIC_ARRAY = 5, TERMINATED_ARRAY = 5,
TERMINATED_ARRAY = 6, UNDEFINED = 6
UNDEFINED = 7
} }
M.typedecl_type = { M.typedecl_type = {

View File

@ -227,7 +227,6 @@ typedef enum
EOLIAN_TYPE_UNKNOWN_TYPE = 0, EOLIAN_TYPE_UNKNOWN_TYPE = 0,
EOLIAN_TYPE_VOID, EOLIAN_TYPE_VOID,
EOLIAN_TYPE_REGULAR, EOLIAN_TYPE_REGULAR,
EOLIAN_TYPE_COMPLEX,
EOLIAN_TYPE_CLASS, EOLIAN_TYPE_CLASS,
EOLIAN_TYPE_STATIC_ARRAY, EOLIAN_TYPE_STATIC_ARRAY,
EOLIAN_TYPE_TERMINATED_ARRAY, EOLIAN_TYPE_TERMINATED_ARRAY,
@ -1761,8 +1760,8 @@ EAPI Eina_Stringshare *eolian_type_file_get(const Eolian_Type *tp);
/* /*
* @brief Get the base type of a type. * @brief Get the base type of a type.
* *
* For pointers, this is the type before the star and for complex types, * Only applies to "complex" ordinary types, i.e. this is the first inner
* this is the first inner type. * type in <>.
* *
* @param[in] tp the type. * @param[in] tp the type.
* @return the base type or NULL. * @return the base type or NULL.
@ -1883,8 +1882,8 @@ EAPI Eina_Bool eolian_type_is_ptr(const Eolian_Type *tp);
EAPI Eina_Stringshare *eolian_type_c_type_get(const Eolian_Type *tp, Eolian_C_Type_Type ctype); EAPI Eina_Stringshare *eolian_type_c_type_get(const Eolian_Type *tp, Eolian_C_Type_Type ctype);
/* /*
* @brief Get the name of the given type. For regular or complex types, this * @brief Get the name of the given type. For regular types, this is for
* is for example "int". For EOLIAN_TYPE_CLASS, this can be "Button". Keep in * example "int". For EOLIAN_TYPE_CLASS, this can be "Button". Keep in
* mind that the name doesn't include namespaces. * mind that the name doesn't include namespaces.
* *
* @param[in] tp the type. * @param[in] tp the type.
@ -1920,8 +1919,9 @@ EAPI Eina_Iterator *eolian_type_namespaces_get(const Eolian_Type *tp);
* @param[in] tp the type. * @param[in] tp the type.
* @return the free func name. * @return the free func name.
* *
* For pointer, class and complex types, this returns name of the func used * For types that translate to C pointers, this is the function used to
* to free the pointer. For other types, this returns NULL. * free them. For other types, this is the function to free a pointer to
* those types.
* *
* @ingroup Eolian * @ingroup Eolian
*/ */

View File

@ -26,13 +26,12 @@ _eval_type(const Eolian_Unit *unit, const Eolian_Expression *expr,
switch (type->type) switch (type->type)
{ {
case EOLIAN_TYPE_CLASS: case EOLIAN_TYPE_CLASS:
case EOLIAN_TYPE_COMPLEX:
return database_expr_eval(unit, expr, EOLIAN_MASK_NULL); return database_expr_eval(unit, expr, EOLIAN_MASK_NULL);
case EOLIAN_TYPE_REGULAR: case EOLIAN_TYPE_REGULAR:
{ {
int kw = eo_lexer_keyword_str_to_id(type->name); if (database_type_is_ownable(type, EINA_FALSE))
if (type->is_ptr)
return database_expr_eval(unit, expr, EOLIAN_MASK_NULL); return database_expr_eval(unit, expr, EOLIAN_MASK_NULL);
int kw = eo_lexer_keyword_str_to_id(type->name);
if (!kw || kw < KW_byte || kw >= KW_void) if (!kw || kw < KW_byte || kw >= KW_void)
{ {
const Eolian_Typedecl *base = eolian_type_typedecl_get(type); const Eolian_Typedecl *base = eolian_type_typedecl_get(type);

View File

@ -120,13 +120,8 @@ 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) Eolian_C_Type_Type ctype)
{ {
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 if ((tp->type == EOLIAN_TYPE_REGULAR
|| tp->type == EOLIAN_TYPE_CLASS
|| tp->type == EOLIAN_TYPE_VOID) || tp->type == EOLIAN_TYPE_VOID)
&& tp->is_const && tp->is_const
&& ((ctype != EOLIAN_C_TYPE_RETURN) || database_type_is_ownable(tp, EINA_FALSE))) && ((ctype != EOLIAN_C_TYPE_RETURN) || database_type_is_ownable(tp, EINA_FALSE)))
@ -134,7 +129,6 @@ database_type_to_str(const Eolian_Type *tp, Eina_Strbuf *buf, const char *name,
eina_strbuf_append(buf, "const "); 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_CLASS) || tp->type == EOLIAN_TYPE_CLASS)
{ {
Eina_List *l; Eina_List *l;
@ -162,7 +156,7 @@ database_type_to_str(const Eolian_Type *tp, Eina_Strbuf *buf, const char *name,
if (tp->is_const && (ctype != EOLIAN_C_TYPE_RETURN)) if (tp->is_const && (ctype != EOLIAN_C_TYPE_RETURN))
eina_strbuf_append(buf, " const"); eina_strbuf_append(buf, " const");
} }
if (tp->type == EOLIAN_TYPE_COMPLEX || tp->type == EOLIAN_TYPE_CLASS) if (tp->type == EOLIAN_TYPE_CLASS)
_buf_add_suffix(buf, "*"); _buf_add_suffix(buf, "*");
if (tp->is_ptr) if (tp->is_ptr)
_buf_add_suffix(buf, "*"); _buf_add_suffix(buf, "*");

View File

@ -160,15 +160,17 @@ _validate_type(Eolian_Type *tp)
case EOLIAN_TYPE_VOID: case EOLIAN_TYPE_VOID:
case EOLIAN_TYPE_UNDEFINED: case EOLIAN_TYPE_UNDEFINED:
return EINA_TRUE; return EINA_TRUE;
case EOLIAN_TYPE_COMPLEX:
if (!tp->freefunc)
{
tp->freefunc = eina_stringshare_add(eo_complex_frees[
eo_lexer_keyword_str_to_id(tp->full_name) - KW_accessor]);
}
return EINA_TRUE;
case EOLIAN_TYPE_REGULAR: case EOLIAN_TYPE_REGULAR:
{ {
if (tp->base_type)
{
if (!tp->freefunc)
{
tp->freefunc = eina_stringshare_add(eo_complex_frees[
eo_lexer_keyword_str_to_id(tp->full_name) - KW_accessor]);
}
return EINA_TRUE;
}
Eolian_Typedecl *tpp; Eolian_Typedecl *tpp;
/* builtins */ /* builtins */
int id = eo_lexer_keyword_str_to_id(tp->full_name); int id = eo_lexer_keyword_str_to_id(tp->full_name);

View File

@ -73,8 +73,9 @@ static const char * const ctypes[] =
NULL, NULL, /* array types */ NULL, NULL, /* array types */
"Eina_Accessor", "Eina_Array", "Eina_Iterator", "Eina_Hash", "Eina_List", "Eina_Accessor *", "Eina_Array *", "Eina_Iterator *", "Eina_Hash *",
"Efl_Future", "Eina_List *",
"Efl_Future *",
"Eina_Value", "char *", "const char *", "Eina_Stringshare *", "Eina_Value", "char *", "const char *", "Eina_Stringshare *",
"void *", "void *",

View File

@ -806,7 +806,6 @@ parse_type_void(Eo_Lexer *ls, Eina_Bool allow_ref, Eina_Bool allow_sarray)
if (tpid >= KW_accessor && tpid <= KW_future) if (tpid >= KW_accessor && tpid <= KW_future)
{ {
int bline = ls->line_number, bcol = ls->column; int bline = ls->line_number, bcol = ls->column;
def->type = EOLIAN_TYPE_COMPLEX;
check_next(ls, '<'); check_next(ls, '<');
if (tpid == KW_future) if (tpid == KW_future)
def->base_type = parse_type_void(ls, EINA_FALSE, EINA_FALSE); def->base_type = parse_type_void(ls, EINA_FALSE, EINA_FALSE);

View File

@ -253,33 +253,45 @@ inline void type_def::set(Eolian_Type const* eolian_type, Eolian_Unit const* uni
{ {
c_type = ::eolian_type_c_type_get(eolian_type, ctype); c_type = ::eolian_type_c_type_get(eolian_type, ctype);
// ::eina_stringshare_del(stringshare); // this crashes // ::eina_stringshare_del(stringshare); // this crashes
Eolian_Type const* stp = eolian_type_base_type_get(eolian_type);
switch( ::eolian_type_type_get(eolian_type)) switch( ::eolian_type_type_get(eolian_type))
{ {
case EOLIAN_TYPE_VOID: case EOLIAN_TYPE_VOID:
original_type = attributes::regular_type_def{"void", {qualifiers(eolian_type), {}}, {}}; original_type = attributes::regular_type_def{"void", {qualifiers(eolian_type), {}}, {}};
break; break;
case EOLIAN_TYPE_REGULAR: case EOLIAN_TYPE_REGULAR:
{ if (!stp)
bool is_undefined = false; {
Eolian_Typedecl const* decl = eolian_type_typedecl_get(eolian_type); bool is_undefined = false;
bool is_function_ptr = decl && eolian_typedecl_type_get(decl) == EOLIAN_TYPEDECL_FUNCTION_POINTER; Eolian_Typedecl const* decl = eolian_type_typedecl_get(eolian_type);
if(decl && eolian_typedecl_type_get(decl) == EOLIAN_TYPEDECL_ALIAS) bool is_function_ptr = decl && eolian_typedecl_type_get(decl) == EOLIAN_TYPEDECL_FUNCTION_POINTER;
{ if(decl && eolian_typedecl_type_get(decl) == EOLIAN_TYPEDECL_ALIAS)
Eolian_Type const* aliased = eolian_typedecl_base_type_get(decl); {
if(aliased && eolian_type_type_get(aliased) == EOLIAN_TYPE_UNDEFINED) Eolian_Type const* aliased = eolian_typedecl_base_type_get(decl);
{ if(aliased && eolian_type_type_get(aliased) == EOLIAN_TYPE_UNDEFINED)
is_undefined = true; {
} is_undefined = true;
} }
}
if(c_type == "va_list *") if(c_type == "va_list *")
throw std::runtime_error(""); throw std::runtime_error("");
std::vector<std::string> namespaces; std::vector<std::string> namespaces;
for(efl::eina::iterator<const char> namespace_iterator( ::eolian_type_namespaces_get(eolian_type)) for(efl::eina::iterator<const char> namespace_iterator( ::eolian_type_namespaces_get(eolian_type))
, namespace_last; namespace_iterator != namespace_last; ++namespace_iterator) , namespace_last; namespace_iterator != namespace_last; ++namespace_iterator)
namespaces.push_back(&*namespace_iterator); namespaces.push_back(&*namespace_iterator);
original_type = {regular_type_def{ ::eolian_type_name_get(eolian_type), {qualifiers(eolian_type), {}}, namespaces, is_undefined, is_function_ptr}}; original_type = {regular_type_def{ ::eolian_type_name_get(eolian_type), {qualifiers(eolian_type), {}}, namespaces, is_undefined, is_function_ptr}};
} }
else
{
complex_type_def complex
{{::eolian_type_name_get(eolian_type), {qualifiers(eolian_type), {}}, {}}, {}};
while (stp)
{
complex.subtypes.push_back({stp, unit, EOLIAN_C_TYPE_DEFAULT});
stp = eolian_type_next_type_get(stp);
}
original_type = complex;
}
break; break;
case EOLIAN_TYPE_CLASS: case EOLIAN_TYPE_CLASS:
{ {
@ -287,19 +299,6 @@ inline void type_def::set(Eolian_Type const* eolian_type, Eolian_Unit const* uni
original_type = klass_name(klass, {qualifiers(eolian_type), {}}); original_type = klass_name(klass, {qualifiers(eolian_type), {}});
} }
break; break;
case EOLIAN_TYPE_COMPLEX:
{
complex_type_def complex
{{::eolian_type_name_get(eolian_type), {qualifiers(eolian_type), {}}, {}}, {}};
Eolian_Type const* stp = eolian_type_base_type_get(eolian_type);
while (stp)
{
complex.subtypes.push_back({stp, unit, EOLIAN_C_TYPE_DEFAULT});
stp = eolian_type_next_type_get(stp);
}
original_type = complex;
}
break;
default: default:
throw std::runtime_error("Type not supported"); throw std::runtime_error("Type not supported");
break; break;

View File

@ -666,7 +666,6 @@ M.Type = Node:clone {
UNKNOWN = eolian.type_type.UNKNOWN, UNKNOWN = eolian.type_type.UNKNOWN,
VOID = eolian.type_type.VOID, VOID = eolian.type_type.VOID,
REGULAR = eolian.type_type.REGULAR, REGULAR = eolian.type_type.REGULAR,
COMPLEX = eolian.type_type.COMPLEX,
CLASS = eolian.type_type.CLASS, CLASS = eolian.type_type.CLASS,
STATIC_ARRAY = eolian.type_type.STATIC_ARRAY, STATIC_ARRAY = eolian.type_type.STATIC_ARRAY,
TERMINATED_ARRAY = eolian.type_type.TERMINATED_ARRAY, TERMINATED_ARRAY = eolian.type_type.TERMINATED_ARRAY,
@ -769,16 +768,17 @@ M.Type = Node:clone {
elseif tpt == self.UNDEFINED then elseif tpt == self.UNDEFINED then
return wrap_type_attrs(self, "__undefined_type") return wrap_type_attrs(self, "__undefined_type")
elseif tpt == self.REGULAR or tpt == self.CLASS then elseif tpt == self.REGULAR or tpt == self.CLASS then
return wrap_type_attrs(self, self:full_name_get())
elseif tpt == self.COMPLEX then
local stypes = {}
local stp = self:base_type_get() local stp = self:base_type_get()
while stp do if stp then
stypes[#stypes + 1] = stp:serialize() local stypes = {}
stp = stp:next_type_get() while stp do
stypes[#stypes + 1] = stp:serialize()
stp = stp:next_type_get()
end
return wrap_type_attrs(self, self:full_name_get() .. "<"
.. table.concat(stypes, ", ") .. ">")
end end
return wrap_type_attrs(self, self:full_name_get() .. "<" return wrap_type_attrs(self, self:full_name_get())
.. table.concat(stypes, ", ") .. ">")
elseif tpt == self.STATIC_ARRAY then elseif tpt == self.STATIC_ARRAY then
return wrap_type_attrs(self, "static_array<" return wrap_type_attrs(self, "static_array<"
.. self:base_type_get():serialize() .. ", " .. self:base_type_get():serialize() .. ", "