static long get_offsetof_offset(const offsetof_expression_t *expression)
{
	type_t *orig_type = expression->type;
	long    offset    = 0;

	designator_t *designator = expression->designator;
	for ( ; designator != NULL; designator = designator->next) {
		type_t *type = skip_typeref(orig_type);

		if (designator->symbol != NULL) {
			assert(is_type_compound(type));
			symbol_t *symbol = designator->symbol;

			compound_t *compound = type->compound.compound;
			entity_t   *iter     = compound->members.first_entity;
			for (; iter->base.symbol != symbol; iter = iter->base.next) {}

			assert(iter->kind == ENTITY_COMPOUND_MEMBER);
			offset += iter->compound_member.offset;

			orig_type = iter->declaration.type;
		} else {
			expression_t *array_index = designator->array_index;
			assert(designator->array_index != NULL);
			assert(is_type_array(type));

			long    index_long   = fold_expression_to_int(array_index);
			type_t *element_type = type->array.element_type;
			long    element_size = get_type_size(element_type);

			/* TODO: check for overflow */
			offset += index_long * element_size;

			orig_type = type->array.element_type;
		}
	}

	return offset;
}
Exemple #2
0
void write_jna_decls(FILE *output, const translation_unit_t *unit)
{
	out          = output;
	global_scope = &unit->scope;

	pset_new_init(&avoid_symbols);

	print_to_file(out);
	fprintf(out, "/* WARNING: Automatically generated file */\n");
	fputs("import com.sun.jna.Native;\n", out);
	fputs("import com.sun.jna.Pointer;\n", out);
	fputs("\n", out);

	const char *register_libname = libname;
	if (register_libname == NULL)
		register_libname = "library";

	/* TODO: where to get the name from? */
	fputs("public class binding {\n", out);
	fputs("\tstatic {\n", out);
	fprintf(out, "\t\tNative.register(\"%s\");\n", register_libname);
	fputs("\t}\n", out);
	fputs("\n", out);

	/* read the avoid list */
	FILE *avoid = fopen("avoid.config", "r");
	if (avoid != NULL) {
		for (;;) {
			char buf[1024];
			char *res = fgets(buf, sizeof(buf), avoid);
			if (res == NULL)
				break;
			if (buf[0] == 0)
				continue;

			size_t len = strlen(buf);
			if (buf[len-1] == '\n')
				buf[len-1] = 0;

			char *str = malloc(len+1);
			memcpy(str, buf, len+1);
			symbol_t *symbol = symbol_table_insert(str);
			pset_new_insert(&avoid_symbols, symbol);
		}
		fclose(avoid);
	}

	/* write structs,unions + enums */
	entity_t *entity = unit->scope.entities;
	for ( ; entity != NULL; entity = entity->base.next) {
		if (entity->kind == ENTITY_ENUM) {
			if (find_enum_typedef(&entity->enume) != NULL)
				continue;
			write_enum(entity->base.symbol, &entity->enume);
		} else if (entity->kind == ENTITY_TYPEDEF) {
			type_t *type = entity->declaration.type;
			if (type->kind == TYPE_ENUM) {
				write_enum(entity->base.symbol, type->enumt.enume);
			}
		}

#if 0
		if (is_type_compound(type)) {
			write_compound(entity->base.symbol, &type->compound);
		}
#endif
	}

	/* write functions */
	entity = unit->scope.entities;
	for ( ; entity != NULL; entity = entity->base.next) {
		if (entity->kind != ENTITY_FUNCTION)
			continue;
		if (entity->base.pos.is_system_header)
			continue;
		if (entity->function.elf_visibility != ELF_VISIBILITY_DEFAULT)
			continue;
		if (output_limits != NULL) {
			bool              in_limits  = false;
			char const *const input_name = entity->base.pos.input_name;
			for (output_limit *limit = output_limits; limit != NULL;
			     limit = limit->next) {
			    if (streq(limit->filename, input_name)) {
					in_limits = true;
					break;
				}
			}
			if (!in_limits)
				continue;
		}

		if (pset_new_contains(&avoid_symbols, entity->base.symbol))
			continue;
		write_function(entity);
	}

	fputs("}\n", out);

	pset_new_destroy(&avoid_symbols);
}