Blame src/logic/amgc_unit_entities.c

7a622c
/**********************************************************/
7a622c
/*  apimagic: cparser-based API normalization utility     */
84312f
/*  Copyright (C) 2015--2021  SysDeer Technologies, LLC   */
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
}