예제 #1
0
파일: type.c 프로젝트: TehMillhouse/cparser
bool types_compatible_ignore_qualifiers(const type_t *type1,
                                        const type_t *type2)
{
	assert(!is_typeref(type1));
	assert(!is_typeref(type2));

	/* shortcut: the same type is always compatible */
	if (type1 == type2)
		return true;

	if (type1->kind != type2->kind) {
		/* enum types are compatible to their base integer type */
		if ((type1->kind == TYPE_ENUM
		     && is_type_atomic(type2, type1->enumt.base.akind))
		    || (type2->kind == TYPE_ENUM
		     && is_type_atomic(type1, type2->enumt.base.akind)))
		    return true;
		/* error types are compatible to everything to avoid follow-up errors */
		if (!is_type_valid(type1) || !is_type_valid(type2))
			return true;
		return false;
	}

	switch (type1->kind) {
	case TYPE_FUNCTION:
		return function_types_compatible(&type1->function, &type2->function);
	case TYPE_ATOMIC:
	case TYPE_IMAGINARY:
	case TYPE_COMPLEX:
		return type1->atomic.akind == type2->atomic.akind;
	case TYPE_ARRAY:
		return array_types_compatible(&type1->array, &type2->array);
	case TYPE_POINTER: {
		const type_t *const to1 = skip_typeref(type1->pointer.points_to);
		const type_t *const to2 = skip_typeref(type2->pointer.points_to);
		return types_compatible(to1, to2);
	}
	case TYPE_REFERENCE: {
		const type_t *const to1 = skip_typeref(type1->reference.refers_to);
		const type_t *const to2 = skip_typeref(type2->reference.refers_to);
		return types_compatible(to1, to2);
	}
	case TYPE_COMPOUND_STRUCT:
	case TYPE_COMPOUND_UNION:
		return type1->compound.compound == type2->compound.compound;
	case TYPE_ENUM:
		return type1->enumt.enume == type2->enumt.enume;
	case TYPE_ERROR:
	case TYPE_VOID:
		return true;
	case TYPE_TYPEDEF:
	case TYPE_TYPEOF:
		break; /* we already tested for is_typeref() above */
	case TYPE_BUILTIN_TEMPLATE:
		panic("unexpected type");
	}
	panic("invalid type kind");
}
예제 #2
0
파일: type.c 프로젝트: TehMillhouse/cparser
type_t *get_default_promoted_type(type_t *orig_type)
{
	type_t *result = orig_type;

	type_t *type = skip_typeref(orig_type);
	if (is_type_integer(type)) {
		result = promote_integer(type);
	} else if (is_type_atomic(type, ATOMIC_TYPE_FLOAT)) {
		result = type_double;
	}

	return result;
}
예제 #3
0
static void write_pointer_type(const pointer_type_t *type)
{
	type_t *orig_points_to = type->points_to;
	type_t *points_to      = skip_typeref(type->points_to);
	if (is_type_atomic(points_to, ATOMIC_TYPE_CHAR)
	    && orig_points_to->kind != TYPE_TYPEDEF) {
		fputs("String", out);
		return;
	}
	if (is_type_pointer(points_to)) {
		/* hack... */
		fputs("java.nio.Buffer", out);
		return;
	}
	fputs("Pointer", out);
}
예제 #4
0
파일: write_fluffy.c 프로젝트: qznc/cparser
static void write_function(const entity_t *entity)
{
	if (entity->function.statement != NULL) {
		fprintf(stderr, "Warning: can't convert function bodies (at %s)\n",
		        entity->base.symbol->string);
	}

	fprintf(out, "func extern %s(", entity->base.symbol->string);

	const function_type_t *function_type
		= (const function_type_t*) entity->declaration.type;

	entity_t *parameter = entity->function.parameters.entities;
	int       first     = 1;
	for( ; parameter != NULL; parameter = parameter->base.next) {
		assert(parameter->kind == ENTITY_PARAMETER);
		if(!first) {
			fprintf(out, ", ");
		} else {
			first = 0;
		}
		if(parameter->base.symbol != NULL) {
			fprintf(out, "%s : ", parameter->base.symbol->string);
		} else {
			fputs("_ : ", out);
		}
		write_type(parameter->declaration.type);
	}
	if(function_type->variadic) {
		if(!first) {
			fprintf(out, ", ");
		} else {
			first = 0;
		}
		fputs("...", out);
	}
	fprintf(out, ")");

	const type_t *return_type = skip_typeref(function_type->return_type);
	if(!is_type_atomic(return_type, ATOMIC_TYPE_VOID)) {
		fprintf(out, " : ");
		write_type(return_type);
	}
	fputc('\n', out);
}
예제 #5
0
ir_tarval *fold_expression(expression_t const *const expr)
{
	switch (expr->kind) {
	case EXPR_CONDITIONAL: {
		conditional_expression_t const *const cond = &expr->conditional;
		if (cond->true_expression != NULL) {
			/* note that we need this if in case of a complex expression as
			 * condition */
			bool condval = fold_expression_to_bool(cond->condition);
			expression_t *res = condval ? cond->true_expression
			                            : cond->false_expression;
			return fold_expression(res);
		}
		ir_tarval *const val = fold_expression(cond->condition);
		return
			tarval_is_null(val)   ? fold_expression(cond->false_expression) :
			cond->true_expression ? fold_expression(cond->true_expression)  :
			val;
	}

	case EXPR_SIZEOF: {
		type_t  *const type = skip_typeref(expr->typeprop.type);
		ir_mode *const mode = get_ir_mode_arithmetic(skip_typeref(expr->base.type));
		return get_type_size_tarval(type, mode);
	}

	case EXPR_ALIGNOF:                    return alignof_to_tarval(                 &expr->typeprop);
	case EXPR_BUILTIN_CONSTANT_P:         return builtin_constant_to_tarval(        &expr->builtin_constant);
	case EXPR_BUILTIN_TYPES_COMPATIBLE_P: return builtin_types_compatible_to_tarval(&expr->builtin_types_compatible);
	case EXPR_CLASSIFY_TYPE:              return classify_type_to_tarval(           &expr->classify_type);
	case EXPR_ENUM_CONSTANT:              return enum_constant_to_tarval(           &expr->reference);
	case EXPR_LITERAL_CASES:              return literal_to_tarval(                 &expr->literal);
	case EXPR_LITERAL_CHARACTER:          return char_literal_to_tarval(            &expr->string_literal);
	case EXPR_OFFSETOF:                   return offsetof_to_tarval(                &expr->offsetofe);
	case EXPR_UNARY_TAKE_ADDRESS:         return fold_expression_to_address(         expr->unary.value);

	case EXPR_UNARY_NEGATE:         return tarval_neg(fold_expression(expr->unary.value));
	case EXPR_UNARY_PLUS:           return fold_expression(expr->unary.value);
	case EXPR_UNARY_COMPLEMENT:     return tarval_not(fold_expression(expr->unary.value));

	case EXPR_UNARY_NOT: {
		type_t    *const type = skip_typeref(expr->base.type);
		ir_mode   *const mode = get_ir_mode_arithmetic(type);
		ir_tarval *const val  = fold_expression(expr->unary.value);
		return create_tarval_from_bool(mode, tarval_is_null(val));
	}

	case EXPR_UNARY_CAST: {
		type_t    *const type = skip_typeref(expr->base.type);
		ir_mode   *const mode = get_ir_mode_arithmetic(type);
		ir_tarval *const val  = fold_expression(expr->unary.value);
		if (is_type_atomic(type, ATOMIC_TYPE_BOOL)) {
			return create_tarval_from_bool(mode, !tarval_is_null(val));
		} else {
			return tarval_convert_to(val, mode);
		}
	}

	case EXPR_BINARY_EQUAL:
	case EXPR_BINARY_NOTEQUAL:
	case EXPR_BINARY_LESS:
	case EXPR_BINARY_LESSEQUAL:
	case EXPR_BINARY_GREATER:
	case EXPR_BINARY_GREATEREQUAL:
	case EXPR_BINARY_ISGREATER:
	case EXPR_BINARY_ISGREATEREQUAL:
	case EXPR_BINARY_ISLESS:
	case EXPR_BINARY_ISLESSEQUAL:
	case EXPR_BINARY_ISLESSGREATER:
	case EXPR_BINARY_ISUNORDERED:
		return fold_binary_comparison(&expr->binary);
	case EXPR_BINARY_ADD:
		return fold_binary_add(&expr->binary);
	case EXPR_BINARY_SUB:
		return fold_binary_sub(&expr->binary);
	case EXPR_BINARY_MUL:
		return fold_binary_expression_arithmetic(&expr->binary, tarval_mul);
	case EXPR_BINARY_DIV:
		return fold_binary_expression_arithmetic(&expr->binary, tarval_div);
	case EXPR_BINARY_MOD:
		return fold_binary_expression_arithmetic(&expr->binary, tarval_mod);
	case EXPR_BINARY_BITWISE_OR:
		return fold_binary_expression_arithmetic(&expr->binary, tarval_or);
	case EXPR_BINARY_BITWISE_AND:
		return fold_binary_expression_arithmetic(&expr->binary, tarval_and);
	case EXPR_BINARY_BITWISE_XOR:
		return fold_binary_expression_arithmetic(&expr->binary, tarval_eor);
	case EXPR_BINARY_SHIFTLEFT:
		return fold_binary_expression_arithmetic(&expr->binary, tarval_shl);
	case EXPR_BINARY_SHIFTRIGHT: {
		fold_binary_func fold = is_type_signed(skip_typeref(expr->base.type))
		                      ? tarval_shrs : tarval_shr;
		return fold_binary_expression_arithmetic(&expr->binary, fold);
	}

	case EXPR_BINARY_LOGICAL_AND: {
		bool const c =
			!tarval_is_null(fold_expression(expr->binary.left)) &&
			!tarval_is_null(fold_expression(expr->binary.right));
		type_t  *const type = skip_typeref(expr->base.type);
		ir_mode *const mode = get_ir_mode_arithmetic(type);
		return create_tarval_from_bool(mode, c);
	}

	case EXPR_BINARY_LOGICAL_OR: {
		bool const c =
			!tarval_is_null(fold_expression(expr->binary.left)) ||
			!tarval_is_null(fold_expression(expr->binary.right));
		type_t  *const type = skip_typeref(expr->base.type);
		ir_mode *const mode = get_ir_mode_arithmetic(type);
		return create_tarval_from_bool(mode, c);
	}

	case EXPR_UNARY_REAL: {
		complex_constant cnst = fold_complex(expr->unary.value);
		return cnst.real;
	}
	case EXPR_UNARY_IMAG: {
		complex_constant cnst = fold_complex(expr->unary.value);
		return cnst.imag;
	}
	case EXPR_CALL:
		return fold_call_builtin(&expr->call);

	case EXPR_ARRAY_ACCESS:
	case EXPR_BINARY_ADD_ASSIGN:
	case EXPR_BINARY_ASSIGN:
	case EXPR_BINARY_BITWISE_AND_ASSIGN:
	case EXPR_BINARY_BITWISE_OR_ASSIGN:
	case EXPR_BINARY_BITWISE_XOR_ASSIGN:
	case EXPR_BINARY_COMMA:
	case EXPR_BINARY_DIV_ASSIGN:
	case EXPR_BINARY_MOD_ASSIGN:
	case EXPR_BINARY_MUL_ASSIGN:
	case EXPR_BINARY_SHIFTLEFT_ASSIGN:
	case EXPR_BINARY_SHIFTRIGHT_ASSIGN:
	case EXPR_BINARY_SUB_ASSIGN:
	case EXPR_COMPOUND_LITERAL:
	case EXPR_ERROR:
	case EXPR_FUNCNAME:
	case EXPR_LABEL_ADDRESS:
	case EXPR_REFERENCE:
	case EXPR_SELECT:
	case EXPR_STATEMENT:
	case EXPR_STRING_LITERAL:
	case EXPR_UNARY_ASSUME:
	case EXPR_UNARY_DELETE:
	case EXPR_UNARY_DELETE_ARRAY:
	case EXPR_UNARY_DEREFERENCE:
	case EXPR_UNARY_POSTFIX_DECREMENT:
	case EXPR_UNARY_POSTFIX_INCREMENT:
	case EXPR_UNARY_PREFIX_DECREMENT:
	case EXPR_UNARY_PREFIX_INCREMENT:
	case EXPR_UNARY_THROW:
	case EXPR_VA_ARG:
	case EXPR_VA_COPY:
	case EXPR_VA_START:
		panic("invalid expression kind for constant folding");
	}

	panic("unexpected expression kind for constant folding");
}