| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| struct amgc_unit_entities_impl { |
| struct amgc_define * adefines; |
| struct amgc_entity * aentities; |
| struct amgc_unit_entities entities; |
| }; |
| |
| static int amgc_free_unit_entities_impl( |
| struct amgc_unit_entities_impl *entities, |
| int status) |
| { |
| if (entities->adefines) |
| free(entities->adefines); |
| |
| if (entities->aentities) |
| free(entities->aentities); |
| |
| free (entities); |
| return status; |
| } |
| |
| int amgc_get_unit_entities( |
| const struct amgc_unit_ctx * uctx, |
| struct amgc_unit_meta * meta, |
| struct amgc_unit_entities ** pentities) |
| { |
| struct amgc_unit_meta umeta; |
| struct amgc_define * adefine; |
| struct amgc_entity * aentity; |
| struct amgc_unit_entities * uentities; |
| union entity_t * entity; |
| union type_t * etype; |
| struct amgc_unit_entities_impl *entities; |
| size_t ndefs; |
| size_t nelements; |
| int enumval; |
| int ptrdepth; |
| |
| if (!meta) |
| meta = &umeta; |
| |
| if (amgc_init_unit_meta(uctx,meta)) |
| return -1; |
| |
| if (!(entities = calloc(1,sizeof(*entities)))) |
| return -1; |
| |
| |
| ndefs = 1; |
| ndefs += meta->ndefines + 1; |
| |
| nelements = 1; |
| nelements += meta->nenums + 1; |
| nelements += meta->nenumvals + 1; |
| nelements += meta->ntypedefs + 1; |
| nelements += meta->nstructs + 1; |
| nelements += meta->nunions + 1; |
| nelements += meta->nfunctions + 1; |
| nelements += meta->ngenerated + 1; |
| |
| if (!(entities->adefines = calloc(ndefs,sizeof(struct amgc_define)))) |
| return amgc_free_unit_entities_impl(entities,-1); |
| |
| if (!(entities->aentities = calloc(nelements,sizeof(struct amgc_entity)))) |
| return amgc_free_unit_entities_impl(entities,-1); |
| |
| adefine = &entities->adefines[1]; |
| entities->entities.defines = adefine; |
| |
| aentity = &entities->aentities[1]; |
| entities->entities.enums = aentity; |
| aentity += meta->nenums + 1; |
| |
| entities->entities.enumvals = aentity; |
| aentity += meta->nenumvals + 1; |
| |
| entities->entities.typedefs = aentity; |
| aentity += meta->ntypedefs + 1; |
| |
| entities->entities.structs = aentity; |
| aentity += meta->nstructs + 1; |
| |
| entities->entities.unions = aentity; |
| aentity += meta->nunions + 1; |
| |
| entities->entities.functions = aentity; |
| aentity += meta->nfunctions + 1; |
| |
| entities->entities.generated = aentity; |
| aentity += meta->ngenerated + 1; |
| |
| meta = &umeta; |
| memset(meta,0,sizeof(*meta)); |
| |
| entity = uctx->ccunit->ast->scope.first_entity; |
| uentities = &entities->entities; |
| |
| for (; entity; entity=entity->base.next) { |
| if (strcmp(*uctx->path,entity->base.pos.input_name)) |
| continue; |
| |
| if ((is_declaration(entity)) && (entity->declaration.implicit)) |
| uentities->generated[meta->ngenerated++].entity = entity; |
| |
| else { |
| switch (entity->kind) { |
| case ENTITY_ENUM: |
| uentities->enums[meta->nenums++].entity = entity; |
| break; |
| |
| case ENTITY_ENUM_VALUE: |
| enumval = (int)get_tarval_long(entity->enum_value.tv); |
| uentities->enumvals[meta->nenumvals].entity = entity; |
| uentities->enumvals[meta->nenumvals].enumval = enumval; |
| meta->nenumvals++; |
| break; |
| |
| case ENTITY_TYPEDEF: |
| etype = entity->declaration.type; |
| ptrdepth = 0; |
| |
| for (; etype->kind == TYPE_POINTER; etype=etype->pointer.points_to) |
| ptrdepth++; |
| |
| uentities->typedefs[meta->ntypedefs].entity = entity; |
| uentities->typedefs[meta->ntypedefs].reftype = etype; |
| uentities->typedefs[meta->ntypedefs].ptrdepth = ptrdepth; |
| meta->ntypedefs++; |
| break; |
| |
| case ENTITY_STRUCT: |
| if (entity->base.symbol || entity->compound.alias) |
| uentities->structs[meta->nstructs++].entity = entity; |
| break; |
| |
| case ENTITY_UNION: |
| if (entity->base.symbol || entity->compound.alias) |
| uentities->unions[meta->nunions++].entity = entity; |
| break; |
| |
| case ENTITY_FUNCTION: |
| uentities->functions[meta->nfunctions++].entity = entity; |
| break; |
| |
| default: |
| break; |
| } |
| } |
| } |
| |
| *pentities = uentities; |
| return 0; |
| } |
| |
| void amgc_free_unit_entities(struct amgc_unit_entities * ctx) |
| { |
| struct amgc_unit_entities_impl *ictx; |
| uintptr_t addr; |
| |
| if (ctx) { |
| addr = (uintptr_t)ctx - offsetof(struct amgc_unit_entities_impl,entities); |
| ictx = (struct amgc_unit_entities_impl *)addr; |
| amgc_free_unit_entities_impl(ictx,0); |
| } |
| } |