Example #1
0
 def test_is_constant_enum(self):
     self.assertTrue(
         ir_util.is_constant(
             ir_pb2.Expression(
                 constant_reference=ir_pb2.Reference(),
                 type=ir_pb2.ExpressionType(enumeration=ir_pb2.EnumType(
                     value="12")))))
Example #2
0
def _check_that_array_base_types_in_structs_are_multiples_of_bytes(
        type_ir, type_definition, source_file_name, errors, ir):
    # TODO(bolms): Remove this limitation.
    """Checks that the sizes of array elements are multiples of 8 bits."""
    if type_ir.base_type.HasField("array_type"):
        # Only check the innermost array for multidimensional arrays.
        return
    assert type_ir.base_type.HasField("atomic_type")
    if type_ir.base_type.HasField("size_in_bits"):
        assert ir_util.is_constant(type_ir.base_type.size_in_bits)
        base_type_size = ir_util.constant_value(type_ir.base_type.size_in_bits)
    else:
        fixed_size = ir_util.fixed_size_of_type_in_bits(type_ir.base_type, ir)
        if fixed_size is None:
            # Variable-sized elements are checked elsewhere.
            return
        base_type_size = fixed_size
    if base_type_size % type_definition.addressable_unit != 0:
        assert type_definition.addressable_unit == ir_pb2.TypeDefinition.BYTE
        errors.append([
            error.error(
                source_file_name, type_ir.base_type.source_location,
                "Array elements in structs must have sizes "
                "which are a multiple of 8 bits.")
        ])
Example #3
0
def _is_constant_integer(attr, module_source_file):
  """Checks if the given attr is an integer constant expression."""
  if (not attr.value.HasField("expression") or
      attr.value.expression.type.WhichOneof("type") != "integer"):
    return [[error.error(module_source_file,
                         attr.value.source_location,
                         _BAD_TYPE_MESSAGE.format(name=attr.name.text,
                                                  type="an integer"))]]
  if not ir_util.is_constant(attr.value.expression):
    return [[error.error(module_source_file,
                         attr.value.source_location,
                         _MUST_BE_CONSTANT_MESSAGE.format(
                             name=attr.name.text))]]
  return []
Example #4
0
def _field_may_have_null_byte_order(field, type_definition, ir):
  """Returns true if "Null" is a valid byte order for the given field."""
  # If the field is one unit in length, then byte order does not matter.
  if (ir_util.is_constant(field.location.size) and
      ir_util.constant_value(field.location.size) == 1):
    return True
  unit = type_definition.addressable_unit
  # Otherwise, if the field's type is either a one-unit-sized type or an array
  # of a one-unit-sized type, then byte order does not matter.
  if (ir_util.fixed_size_of_type_in_bits(ir_util.get_base_type(field.type), ir)
      == unit):
    return True
  # In all other cases, byte order does matter.
  return False
Example #5
0
def _compute_constant_value_of_constant_reference(expression, ir):
    referred_object = ir_util.find_object(
        expression.constant_reference.canonical_name, ir)
    if isinstance(referred_object, ir_pb2.EnumValue):
        compute_constraints_of_expression(referred_object.value, ir)
        assert ir_util.is_constant(referred_object.value)
        new_value = str(ir_util.constant_value(referred_object.value))
        expression.type.enumeration.value = new_value
    elif isinstance(referred_object, ir_pb2.Field):
        assert ir_util.field_is_virtual(referred_object), (
            "Non-virtual non-enum-value constant reference should have been caught "
            "in type_check.py")
        compute_constraints_of_expression(referred_object.read_transform, ir)
        expression.type.CopyFrom(referred_object.read_transform.type)
    else:
        assert False, "Unexpected constant reference type."
Example #6
0
def _compute_constant_value_of_comparison_operator(expression):
    """Computes the constant value, if any, of a comparison operator."""
    args = expression.function.args
    if all(ir_util.is_constant(arg) for arg in args):
        functions = {
            ir_pb2.Function.EQUALITY: operator.eq,
            ir_pb2.Function.INEQUALITY: operator.ne,
            ir_pb2.Function.LESS: operator.lt,
            ir_pb2.Function.LESS_OR_EQUAL: operator.le,
            ir_pb2.Function.GREATER: operator.gt,
            ir_pb2.Function.GREATER_OR_EQUAL: operator.ge,
            ir_pb2.Function.AND: operator.and_,
            ir_pb2.Function.OR: operator.or_,
        }
        func = functions[expression.function.function]
        expression.type.boolean.value = func(
            *[ir_util.constant_value(arg) for arg in args])
Example #7
0
def _check_that_inner_array_dimensions_are_constant(type_ir, source_file_name,
                                                    errors):
    """Checks that inner array dimensions are constant."""
    if type_ir.WhichOneof("size") == "automatic":
        errors.append([
            error.error(
                source_file_name, type_ir.element_count.source_location,
                "Array dimensions can only be omitted for the outermost dimension."
            )
        ])
    elif type_ir.WhichOneof("size") == "element_count":
        if not ir_util.is_constant(type_ir.element_count):
            errors.append([
                error.error(source_file_name,
                            type_ir.element_count.source_location,
                            "Inner array dimensions must be constant.")
            ])
    else:
        assert False, 'Expected "element_count" or "automatic" array size.'
Example #8
0
 def test_is_constant_boolean(self):
     self.assertTrue(ir_util.is_constant(_parse_expression("true")))
     expression = _parse_expression("true")
     # The type information should be ignored for constants like this one.
     expression.type.boolean.CopyFrom(ir_pb2.BooleanType())
     self.assertTrue(ir_util.is_constant(expression))
Example #9
0
 def test_is_constant_integer(self):
     self.assertTrue(ir_util.is_constant(_parse_expression("6")))
     expression = _parse_expression("12")
     # The type information should be ignored for constants like this one.
     expression.type.integer.CopyFrom(ir_pb2.IntegerType())
     self.assertTrue(ir_util.is_constant(expression))