|
|
7a622c |
/**********************************************************/
|
|
|
7a622c |
/* apimagic: cparser-based API normalization utility */
|
|
|
7a622c |
/* Copyright (C) 2015--2016 Z. Gilboa */
|
|
|
7a622c |
/* Released under GPLv2 and GPLv3; see COPYING.APIMAGIC. */
|
|
|
7a622c |
/**********************************************************/
|
|
|
7a622c |
|
|
|
7a622c |
#include <cparser/ast/ast_t.h>
|
|
|
7a622c |
#include <cparser/ast/entity_t.h>
|
|
|
3aebba |
#include <cparser/ast/type_t.h>
|
|
|
9ea4a3 |
#include <libfirm/tv.h>
|
|
|
7a622c |
|
|
|
7a622c |
#include <apimagic/apimagic.h>
|
|
|
7a622c |
|
|
|
7a622c |
struct amgc_unit_entities_impl {
|
|
|
7a622c |
struct amgc_define * adefines;
|
|
|
7a622c |
struct amgc_entity * aentities;
|
|
|
7a622c |
struct amgc_unit_entities entities;
|
|
|
7a622c |
};
|
|
|
7a622c |
|
|
|
7a622c |
static int amgc_free_unit_entities_impl(
|
|
|
7a622c |
struct amgc_unit_entities_impl *entities,
|
|
|
7a622c |
int status)
|
|
|
7a622c |
{
|
|
|
7a622c |
if (entities->adefines)
|
|
|
7a622c |
free(entities->adefines);
|
|
|
7a622c |
|
|
|
7a622c |
if (entities->aentities)
|
|
|
7a622c |
free(entities->aentities);
|
|
|
7a622c |
|
|
|
7a622c |
free (entities);
|
|
|
7a622c |
return status;
|
|
|
7a622c |
}
|
|
|
7a622c |
|
|
|
7a622c |
int amgc_get_unit_entities(
|
|
|
7a622c |
const struct amgc_unit_ctx * uctx,
|
|
|
7a622c |
struct amgc_unit_meta * meta,
|
|
|
7a622c |
struct amgc_unit_entities ** pentities)
|
|
|
7a622c |
{
|
|
|
7a622c |
struct amgc_unit_meta umeta;
|
|
|
7a622c |
struct amgc_define * adefine;
|
|
|
7a622c |
struct amgc_entity * aentity;
|
|
|
7a622c |
struct amgc_unit_entities * uentities;
|
|
|
7a622c |
union entity_t * entity;
|
|
|
3aebba |
union type_t * etype;
|
|
|
7a622c |
struct amgc_unit_entities_impl *entities;
|
|
|
7a622c |
size_t ndefs;
|
|
|
7a622c |
size_t nelements;
|
|
|
9ea4a3 |
int enumval;
|
|
|
3aebba |
int ptrdepth;
|
|
|
7a622c |
|
|
|
7a622c |
if (!meta)
|
|
|
7a622c |
meta = &umeta;
|
|
|
7a622c |
|
|
|
7a622c |
if (amgc_init_unit_meta(uctx,meta))
|
|
|
7a622c |
return -1;
|
|
|
7a622c |
|
|
|
7a622c |
if (!(entities = calloc(1,sizeof(*entities))))
|
|
|
7a622c |
return -1;
|
|
|
7a622c |
|
|
|
7a622c |
/* use first element as a guard */
|
|
|
7a622c |
ndefs = 1;
|
|
|
7a622c |
ndefs += meta->ndefines + 1;
|
|
|
7a622c |
|
|
|
7a622c |
nelements = 1;
|
|
|
7a622c |
nelements += meta->nenums + 1;
|
|
|
7a622c |
nelements += meta->nenumvals + 1;
|
|
|
7a622c |
nelements += meta->ntypedefs + 1;
|
|
|
7a622c |
nelements += meta->nstructs + 1;
|
|
|
7a622c |
nelements += meta->nunions + 1;
|
|
|
7a622c |
nelements += meta->nfunctions + 1;
|
|
|
7a622c |
nelements += meta->ngenerated + 1;
|
|
|
7a622c |
|
|
|
7a622c |
if (!(entities->adefines = calloc(ndefs,sizeof(struct amgc_define))))
|
|
|
7a622c |
return amgc_free_unit_entities_impl(entities,-1);
|
|
|
7a622c |
|
|
|
7a622c |
if (!(entities->aentities = calloc(nelements,sizeof(struct amgc_entity))))
|
|
|
7a622c |
return amgc_free_unit_entities_impl(entities,-1);
|
|
|
7a622c |
|
|
|
7a622c |
adefine = &entities->adefines[1];
|
|
|
7a622c |
entities->entities.defines = adefine;
|
|
|
7a622c |
|
|
|
7a622c |
aentity = &entities->aentities[1];
|
|
|
7a622c |
entities->entities.enums = aentity;
|
|
|
7a622c |
aentity += meta->nenums + 1;
|
|
|
7a622c |
|
|
|
7a622c |
entities->entities.enumvals = aentity;
|
|
|
7a622c |
aentity += meta->nenumvals + 1;
|
|
|
7a622c |
|
|
|
7a622c |
entities->entities.typedefs = aentity;
|
|
|
7a622c |
aentity += meta->ntypedefs + 1;
|
|
|
7a622c |
|
|
|
7a622c |
entities->entities.structs = aentity;
|
|
|
7a622c |
aentity += meta->nstructs + 1;
|
|
|
7a622c |
|
|
|
7a622c |
entities->entities.unions = aentity;
|
|
|
7a622c |
aentity += meta->nunions + 1;
|
|
|
7a622c |
|
|
|
7a622c |
entities->entities.functions = aentity;
|
|
|
7a622c |
aentity += meta->nfunctions + 1;
|
|
|
7a622c |
|
|
|
7a622c |
entities->entities.generated = aentity;
|
|
|
7a622c |
aentity += meta->ngenerated + 1;
|
|
|
7a622c |
|
|
|
7a622c |
meta = &umeta;
|
|
|
7a622c |
memset(meta,0,sizeof(*meta));
|
|
|
7a622c |
|
|
|
7a622c |
entity = uctx->ccunit->ast->scope.first_entity;
|
|
|
7a622c |
uentities = &entities->entities;
|
|
|
7a622c |
|
|
|
7a622c |
for (; entity; entity=entity->base.next) {
|
|
|
7a622c |
if (strcmp(*uctx->path,entity->base.pos.input_name))
|
|
|
7a622c |
continue;
|
|
|
7a622c |
|
|
|
7a622c |
if ((is_declaration(entity)) && (entity->declaration.implicit))
|
|
|
7a622c |
uentities->generated[meta->ngenerated++].entity = entity;
|
|
|
7a622c |
|
|
|
7a622c |
else {
|
|
|
7a622c |
switch (entity->kind) {
|
|
|
7a622c |
case ENTITY_ENUM:
|
|
|
7a622c |
uentities->enums[meta->nenums++].entity = entity;
|
|
|
7a622c |
break;
|
|
|
7a622c |
|
|
|
7a622c |
case ENTITY_ENUM_VALUE:
|
|
|
9ea4a3 |
enumval = (int)get_tarval_long(entity->enum_value.tv);
|
|
|
9ea4a3 |
uentities->enumvals[meta->nenumvals].entity = entity;
|
|
|
9ea4a3 |
uentities->enumvals[meta->nenumvals].enumval = enumval;
|
|
|
9ea4a3 |
meta->nenumvals++;
|
|
|
7a622c |
break;
|
|
|
7a622c |
|
|
|
7a622c |
case ENTITY_TYPEDEF:
|
|
|
3aebba |
etype = entity->declaration.type;
|
|
|
3aebba |
ptrdepth = 0;
|
|
|
3aebba |
|
|
|
3aebba |
for (; etype->kind == TYPE_POINTER; etype=etype->pointer.points_to)
|
|
|
3aebba |
ptrdepth++;
|
|
|
3aebba |
|
|
|
047bc5 |
uentities->typedefs[meta->ntypedefs].entity = entity;
|
|
|
91ea2c |
uentities->typedefs[meta->ntypedefs].reftype = etype;
|
|
|
3aebba |
uentities->typedefs[meta->ntypedefs].ptrdepth = ptrdepth;
|
|
|
7a622c |
meta->ntypedefs++;
|
|
|
7a622c |
break;
|
|
|
7a622c |
|
|
|
7a622c |
case ENTITY_STRUCT:
|
|
|
7a622c |
if (entity->base.symbol || entity->compound.alias)
|
|
|
7a622c |
uentities->structs[meta->nstructs++].entity = entity;
|
|
|
7a622c |
break;
|
|
|
7a622c |
|
|
|
7a622c |
case ENTITY_UNION:
|
|
|
7a622c |
if (entity->base.symbol || entity->compound.alias)
|
|
|
7a622c |
uentities->unions[meta->nunions++].entity = entity;
|
|
|
7a622c |
break;
|
|
|
7a622c |
|
|
|
7a622c |
case ENTITY_FUNCTION:
|
|
|
7a622c |
uentities->functions[meta->nfunctions++].entity = entity;
|
|
|
7a622c |
break;
|
|
|
7a622c |
|
|
|
7a622c |
default:
|
|
|
7a622c |
break;
|
|
|
7a622c |
}
|
|
|
7a622c |
}
|
|
|
7a622c |
}
|
|
|
7a622c |
|
|
|
7a622c |
*pentities = uentities;
|
|
|
7a622c |
return 0;
|
|
|
7a622c |
}
|
|
|
7a622c |
|
|
|
7a622c |
void amgc_free_unit_entities(struct amgc_unit_entities * ctx)
|
|
|
7a622c |
{
|
|
|
7a622c |
struct amgc_unit_entities_impl *ictx;
|
|
|
7a622c |
uintptr_t addr;
|
|
|
7a622c |
|
|
|
7a622c |
if (ctx) {
|
|
|
7a622c |
addr = (uintptr_t)ctx - offsetof(struct amgc_unit_entities_impl,entities);
|
|
|
7a622c |
ictx = (struct amgc_unit_entities_impl *)addr;
|
|
|
7a622c |
amgc_free_unit_entities_impl(ictx,0);
|
|
|
7a622c |
}
|
|
|
7a622c |
}
|