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"); }
bool types_compatible(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 (!is_type_valid(type1) || !is_type_valid(type2)) return true; if (type1->base.qualifiers != type2->base.qualifiers) return false; if (type1->kind != type2->kind) 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: { break; } case TYPE_ENUM: /* TODO: not implemented */ break; case TYPE_ERROR: /* Hmm, the error type should be compatible to all other types */ return true; case TYPE_TYPEDEF: case TYPE_TYPEOF: panic("typerefs not skipped in compatible types?!?"); } return false; }
bool types_compatible(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->base.qualifiers == type2->base.qualifiers && type1->kind == type2->kind) { 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: break; case TYPE_ENUM: /* TODO: not implemented */ break; case TYPE_ERROR: case TYPE_VOID: return true; case TYPE_TYPEDEF: case TYPE_TYPEOF: panic("typeref not skipped"); case TYPE_BUILTIN_TEMPLATE: panic("unexpected type"); } } return !is_type_valid(type1) || !is_type_valid(type2); }
type_t *get_qualified_type(type_t *orig_type, type_qualifiers_t const qual) { type_t *type = skip_typeref(orig_type); type_t *copy; if (is_type_array(type)) { /* For array types the element type has to be adjusted */ type_t *element_type = type->array.element_type; type_t *qual_element_type = get_qualified_type(element_type, qual); if (qual_element_type == element_type) return orig_type; copy = duplicate_type(type); copy->array.element_type = qual_element_type; } else if (is_type_valid(type)) { if ((type->base.qualifiers & qual) == (int)qual) return orig_type; copy = duplicate_type(type); copy->base.qualifiers |= qual; } else { return type; } return identify_new_type(copy); }
int idmef_value_type_compare(const idmef_value_type_t *type1, const idmef_value_type_t *type2, idmef_criterion_operator_t op) { int ret; ret = is_type_valid(type1->id); if ( ret < 0 ) return ret; if ( type1->id != type2->id ) { if ( type1->id != IDMEF_VALUE_TYPE_ENUM && type2->id != IDMEF_VALUE_TYPE_STRING ) return requiem_error(REQUIEM_ERROR_IDMEF_VALUE_TYPE_COMPARE_MISMATCH); } assert(op & ops_tbl[type1->id].operator); if ( ! ops_tbl[type1->id].compare ) return requiem_error_verbose(REQUIEM_ERROR_IDMEF_VALUE_TYPE_COMPARE_UNAVAILABLE, "Object type '%s' does not support compare operation", idmef_value_type_to_string(type1->id)); ret = ops_tbl[type1->id].compare(type1, type2, ops_tbl[type1->id].len, op & ~IDMEF_CRITERION_OPERATOR_NOT); if ( ret < 0 ) /* not an error -> no match */ ret = 1; if ( op & IDMEF_CRITERION_OPERATOR_NOT ) return (ret == 0) ? 1 : 0; else return ret; }
void layout_union_type(compound_type_t *type) { assert(type->compound != NULL); compound_t *compound = type->compound; if (! compound->complete) return; il_size_t size = 0; il_alignment_t alignment = compound->alignment; entity_t *entry = compound->members.entities; for (; entry != NULL; entry = entry->base.next) { if (entry->kind != ENTITY_COMPOUND_MEMBER) continue; type_t *m_type = skip_typeref(entry->declaration.type); if (! is_type_valid(skip_typeref(m_type))) continue; entry->compound_member.offset = 0; il_size_t m_size = get_type_size(m_type); if (m_size > size) size = m_size; il_alignment_t m_alignment = get_type_alignment_compound(m_type); if (m_alignment > alignment) alignment = m_alignment; } size = (size + alignment - 1) & -alignment; compound->size = size; compound->alignment = alignment; }
const char *idmef_value_type_to_string(idmef_value_type_id_t type) { int ret; ret = is_type_valid(type); if ( ret < 0 ) return NULL; return ops_tbl[type].name; }
nas_acl_action_t::nas_acl_action_t (BASE_ACL_ACTION_TYPE_t t) { if (!is_type_valid (t)) { throw nas::base_exception {NAS_ACL_E_ATTR_VAL, __PRETTY_FUNCTION__, std::string {"Invalid action type "} + std::to_string (t)}; } memset (&_a_info, 0, sizeof (_a_info)); _a_info.action_type = t; _a_info.values_type = NDI_ACL_ACTION_NO_VALUE; }
int idmef_value_type_get_applicable_operators(idmef_value_type_id_t type, idmef_criterion_operator_t *result) { int ret; ret = is_type_valid(type); if ( ret < 0 ) return ret; *result = ops_tbl[type].operator; return 0; }
void idmef_value_type_destroy(idmef_value_type_t *type) { int ret; ret = is_type_valid(type->id); if ( ret < 0 ) return; if ( ! ops_tbl[type->id].destroy ) return; ops_tbl[type->id].destroy(type); }
int idmef_value_type_check_operator(idmef_value_type_id_t type, idmef_criterion_operator_t op) { int ret; ret = is_type_valid(type); if ( ret < 0 ) return ret; if ( (~ops_tbl[type].operator & op) == 0 ) return 0; return requiem_error_verbose(REQUIEM_ERROR_IDMEF_CRITERION_UNSUPPORTED_OPERATOR, "Object type '%s' does not support operator '%s'", idmef_value_type_to_string(type), idmef_criterion_operator_to_string(op)); }
int idmef_value_type_write(const idmef_value_type_t *src, requiem_string_t *out) { int ret; ret = is_type_valid(src->id); if ( ret < 0 ) return ret; if ( ! ops_tbl[src->id].write ) return requiem_error_verbose(REQUIEM_ERROR_IDMEF_VALUE_TYPE_WRITE_UNAVAILABLE, "Object type '%s' does not support write operation", idmef_value_type_to_string(src->id)); return ops_tbl[src->id].write(src, out); }
int idmef_value_type_ref(const idmef_value_type_t *vt) { int ret; ret = is_type_valid(vt->id); if ( ret < 0 ) return ret; if ( ! ops_tbl[vt->id].ref ) return requiem_error_verbose(REQUIEM_ERROR_IDMEF_VALUE_TYPE_REF_UNAVAILABLE, "Object type '%s' does not support ref operation", idmef_value_type_to_string(vt->id)); return ops_tbl[vt->id].ref(vt); }
int idmef_value_type_copy(const idmef_value_type_t *src, void *dst) { int ret; ret = is_type_valid(src->id); if ( ret < 0 ) return ret; if ( ! ops_tbl[src->id].copy ) return requiem_error_verbose(REQUIEM_ERROR_IDMEF_VALUE_TYPE_COPY_UNAVAILABLE, "Object type '%s' does not support copy operation", idmef_value_type_to_string(src->id)); return ops_tbl[src->id].copy(src, dst, ops_tbl[src->id].len); }
int idmef_value_type_read(idmef_value_type_t *dst, const char *buf) { int ret; ret = is_type_valid(dst->id); if ( ret < 0 ) return ret; if ( ! ops_tbl[dst->id].read ) return requiem_error_verbose(REQUIEM_ERROR_IDMEF_VALUE_TYPE_READ_UNAVAILABLE, "Object type '%s' does not support read operation", idmef_value_type_to_string(dst->id)); ret = ops_tbl[dst->id].read(dst, buf); return (ret < 0) ? ret : 0; }
int idmef_value_type_clone(const idmef_value_type_t *src, idmef_value_type_t *dst) { int ret; assert(dst->id == src->id); ret = is_type_valid(dst->id); if ( ret < 0 ) return ret; if ( ! ops_tbl[dst->id].clone ) return requiem_error_verbose(REQUIEM_ERROR_IDMEF_VALUE_TYPE_CLONE_UNAVAILABLE, "Object type '%s' does not support clone operation", idmef_value_type_to_string(dst->id)); return ops_tbl[dst->id].clone(src, dst, ops_tbl[dst->id].len); }
void determine_enum_values(enum_t *const enume) { if (enume->error) return; ir_mode *const mode = atomic_modes[enume->akind]; ir_tarval *const one = get_mode_one(mode); ir_tarval * tv_next = get_mode_null(mode); for (entity_t *entry = enume->first_value; entry != NULL && entry->kind == ENTITY_ENUM_VALUE; entry = entry->base.next) { expression_t *const init = entry->enum_value.value; if (init != NULL) { type_t *const init_type = skip_typeref(init->base.type); if (!is_type_valid(init_type)) continue; tv_next = fold_expression(init); } assert(entry->enum_value.tv == NULL || entry->enum_value.tv == tv_next); entry->enum_value.tv = tv_next; tv_next = tarval_add(tv_next, one); } }
void layout_compound(compound_t *const compound) { bool const is_union = compound->base.kind == ENTITY_UNION; bool const is_packed = compound->packed; il_alignment_t alignment = compound->alignment; size_t bit_offset = 0; il_size_t size = 0; bool need_pad = false; for (entity_t *entry = compound->members.entities; entry; entry = entry->base.next) { if (entry->kind != ENTITY_COMPOUND_MEMBER) continue; compound_member_t *const member = &entry->compound_member; type_t *const m_type = skip_typeref(member->base.type); if (!is_type_valid(m_type)) continue; if (is_packed) { /* GCC: Specifying this attribute for `struct' and `union' types is * equivalent to specifying the `packed' attribute on each of the * structure or union members. */ member->base.alignment = 1; } il_alignment_t const m_alignment = member->base.alignment; alignment = MAX(alignment, m_alignment); unsigned const m_size = get_type_size(m_type); if (is_union) { size = MAX(size, m_size); } else if (member->bitfield) { il_alignment_t const alignment_mask = m_alignment - 1; size_t const base_size = m_size * BITS_PER_BYTE; size_t const bit_size = member->bit_size; if (!is_packed) { bit_offset += (size & alignment_mask) * BITS_PER_BYTE; size &= ~alignment_mask; if (bit_offset + bit_size > base_size || bit_size == 0) { size += (bit_offset + BITS_PER_BYTE - 1) / BITS_PER_BYTE; size = round_up2(size, m_alignment); bit_offset = 0; } } if (target.byte_order_big_endian) { member->offset = size & ~alignment_mask; member->bit_offset = base_size - bit_offset - bit_size; } else { member->offset = size; member->bit_offset = bit_offset; } bit_offset += bit_size; size += bit_offset / BITS_PER_BYTE; bit_offset %= BITS_PER_BYTE; } else { if (bit_offset != 0) { bit_offset = 0; size += 1; } il_size_t const new_size = round_up2(size, m_alignment); if (new_size > size) { need_pad = true; size = new_size; } member->offset = size; size += m_size; } } if (bit_offset != 0) size += 1; il_size_t const new_size = round_up2(size, alignment); if (new_size > size) { need_pad = true; size = new_size; } position_t const *const pos = &compound->base.pos; if (need_pad) { warningf(WARN_PADDED, pos, "'%N' needs padding", compound); } else if (is_packed) { warningf(WARN_PACKED, pos, "superfluous packed attribute on '%N'", compound); } compound->size = size; compound->alignment = alignment; }
void layout_compound(compound_t *const compound) { bool const is_union = compound->base.kind == ENTITY_UNION; unsigned alignment = compound->alignment; size_t bit_offset = 0; unsigned size = 0; bool need_pad = false; for (entity_t *entry = compound->members.first_entity; entry; entry = entry->base.next) { if (entry->kind != ENTITY_COMPOUND_MEMBER) continue; compound_member_t *const member = &entry->compound_member; type_t *const m_type = skip_typeref(member->base.type); if (!is_type_valid(m_type)) continue; unsigned m_alignment = get_declaration_alignment(&member->base); alignment = MAX(alignment, m_alignment); unsigned const m_size = get_ctype_size(m_type); if (is_union) { size = MAX(size, m_size); } else if (member->bitfield) { unsigned const alignment_mask = m_alignment - 1; size_t const base_size = m_size * BITS_PER_BYTE; size_t const bit_size = member->bit_size; bit_offset += (size & alignment_mask) * BITS_PER_BYTE; size &= ~alignment_mask; if (bit_offset + bit_size > base_size || (bit_size == 0 && !(member->base.modifiers & DM_PACKED))) { size += (bit_offset + BITS_PER_BYTE - 1) / BITS_PER_BYTE; size = round_up2(size, m_alignment); bit_offset = 0; } if (target.byte_order_big_endian) { member->offset = size & ~alignment_mask; member->bit_offset = base_size - bit_offset - bit_size; } else { member->offset = size; member->bit_offset = bit_offset; } bit_offset += bit_size; size += bit_offset / BITS_PER_BYTE; bit_offset %= BITS_PER_BYTE; } else { if (bit_offset != 0) { bit_offset = 0; size += 1; } unsigned const new_size = round_up2(size, m_alignment); if (new_size > size) { need_pad = true; size = new_size; } member->offset = size; size += m_size; } } if (bit_offset != 0) size += 1; unsigned const new_size = round_up2(size, alignment); if (new_size > size) { need_pad = true; size = new_size; } position_t const *const pos = &compound->base.pos; if (need_pad) { warningf(WARN_PADDED, pos, "%N needs padding", compound); } else if (compound->packed) { warningf(WARN_PACKED, pos, "superfluous packed attribute on %N", compound); } compound->size = size; compound->alignment = alignment; }
void layout_struct_type(compound_type_t *type) { assert(type->compound != NULL); compound_t *compound = type->compound; if (!compound->complete) return; if (type->compound->layouted) return; il_size_t offset = 0; il_alignment_t alignment = compound->alignment; bool need_pad = false; entity_t *entry = compound->members.entities; while (entry != NULL) { if (entry->kind != ENTITY_COMPOUND_MEMBER) { entry = entry->base.next; continue; } type_t *const m_type = skip_typeref(entry->declaration.type); if (!is_type_valid(m_type)) { entry = entry->base.next; continue; } if (entry->compound_member.bitfield) { entry = pack_bitfield_members(&offset, &alignment, compound->packed, entry); continue; } il_alignment_t m_alignment = get_type_alignment_compound(m_type); if (m_alignment > alignment) alignment = m_alignment; if (!compound->packed) { il_size_t new_offset = (offset + m_alignment-1) & -m_alignment; if (new_offset > offset) { need_pad = true; offset = new_offset; } } entry->compound_member.offset = offset; offset += get_type_size(m_type); entry = entry->base.next; } if (!compound->packed) { il_size_t new_offset = (offset + alignment-1) & -alignment; if (new_offset > offset) { need_pad = true; offset = new_offset; } } source_position_t const *const pos = &compound->base.source_position; if (need_pad) { warningf(WARN_PADDED, pos, "'%T' needs padding", type); } else if (compound->packed) { warningf(WARN_PACKED, pos, "superfluous packed attribute on '%T'", type); } compound->size = offset; compound->alignment = alignment; compound->layouted = true; }