)
element.serialize(translation_unit, 'a.xml', 'utf-8')
translation_unit = element.deserialize('a.xml', t_def.factory, 'utf-8')
+translation_unit.fix_type_sharing()
element.serialize(translation_unit, 'b.xml', 'utf-8')
translation_unit.strip_scope_analysis()
element.serialize(translation_unit, 'c.xml', 'utf-8')
translation_unit.scope = t_def.Scope()
translation_unit.post_process(post_process.Context())
element.serialize(translation_unit, 'd.xml', 'utf-8')
+translation_unit = element.deserialize('d.xml', t_def.factory, 'utf-8')
+translation_unit.fix_type_sharing()
+element.serialize(translation_unit, 'e.xml', 'utf-8')
#translation_unit.strip_redundancy()
-#element.serialize(translation_unit, 'e.xml', 'utf-8')
+#element.serialize(translation_unit, 'f.xml', 'utf-8')
int size;
int align = 1;
dict(str, ref) identifiers;
- dict(str, ref) enum_tags;
dict(str, ref) struct_tags;
dict(str, ref) union_tags;
+ dict(str, ref) enum_tags;
};
/* type analysis */
int align = 1;
};
class TypeVoid: Type;
+class TypeBool: Type;
class TypeInt: Type;
class TypeIntSigned: TypeInt;
class TypeEnum: TypeIntSigned {
};
class TypeIntUnsigned: TypeInt;
class TypeFloat: Type;
-class TypeFloat: TypeFloat;
+class TypeFloatReal: TypeFloat;
class TypeFloatImaginary: TypeFloat;
class TypeFloatComplex: TypeFloat;
-class TypeBool: Type;
class TypePointer: Type {
ref target_type;
};
%%
+# primitive types
+type_void = TypeVoid(size = 0)
+type_bool = TypeBool(rank = 0, size = 1)
+type_signed_char = TypeIntSigned(rank = 1, size = 1)
+type_unsigned_char = TypeIntUnsigned(rank = 2, size = 1)
+type_signed_short = TypeIntSigned(rank = 3, size = 2, align = 2)
+type_unsigned_short = TypeIntUnsigned(rank = 4, size = 2, align = 2)
+type_signed_int = TypeIntSigned(rank = 5, size = 4, align = 4)
+type_unsigned_int = TypeIntUnsigned(rank = 6, size = 4, align = 4)
+type_signed_long = TypeIntSigned(rank = 7, size = 8, align = 8)
+type_unsigned_long = TypeIntUnsigned(rank = 8, size = 8, align = 8)
+type_signed_long_long = TypeIntSigned(rank = 9, size = 16, align = 16)
+type_unsigned_long_long = TypeIntUnsigned(rank = 10, size = 16, align = 16)
+type_float = TypeFloatReal(rank = 11, size = 4, align = 4)
+type_float_imaginary = TypeFloatImaginary(rank = 12, size = 4, align = 4)
+type_float_complex = TypeFloatComplex(rank = 13, size = 8, align = 4)
+type_double = TypeFloatReal(rank = 14, size = 8, align = 8)
+type_double_imaginary = TypeFloatImaginary(rank = 15, size = 8, align = 8)
+type_double_complex = TypeFloatComplex(rank = 16, size = 16, align = 8)
+type_long_double = TypeFloatReal(rank = 17, size = 16, align = 16)
+type_long_double_imaginary = TypeFloatImaginary(rank = 18, size = 16, align = 16)
+type_long_double_complex = TypeFloatComplex(rank = 19, size = 32, align = 16)
+
+type_ssize_t = type_signed_int
+assert type_ssize_t.size == POINTER_SIZE
+type_size_t = type_unsigned_int
+assert type_size_t.size == POINTER_SIZE
+
+rank_to_type = [
+ type_bool, # 0
+ type_signed_char, # 1
+ type_unsigned_char, # 2
+ type_signed_short, # 3
+ type_unsigned_short, # 4
+ type_signed_int, # 5
+ type_unsigned_int, # 6
+ type_signed_long, # 7
+ type_unsigned_long, # 8
+ type_signed_long_long, # 9
+ type_unsigned_long_long, # 10
+ type_float, # 11
+ type_float_imaginary, # 12
+ type_float_complex, # 13
+ type_double, # 14
+ type_double_imaginary, # 15
+ type_double_complex, # 16
+ type_long_double, # 17
+ type_long_double_imaginary, # 18
+ type_long_double_complex # 19
+]
+
+# note: ranks must also match calc_type.complex_promotions
+
def factory(tag, *args, **kwargs):
return tag_to_class[tag](*args, **kwargs)
isinstance(parameter_declaration.children[1], DeclaratorAbstract)
)
-@method(TypeStructOrUnion.Member)
-def __eq__(self, rhs):
- return (
- self.name == rhs.name and
- self.type == rhs.type and
- self.offset == rhs.offset
- )
-del __eq__
-
@method(Type)
def __eq__(self, rhs):
return (
)
del __eq__
+@method(TypeStructOrUnion.Member)
+def __eq__(self, rhs):
+ return (
+ self.name == rhs.name and
+ self.type == rhs.type and
+ self.offset == rhs.offset
+ )
+del __eq__
+
@method(Node)
def strip_redundancy(self):
self.text = [''] * (len(self.children) + 1)
# temporary
@method(Node)
def strip_scope_analysis(self):
- for i in self.children:
- i.strip_scope_analysis()
+ for i in range(len(self.children)):
+ self.children[i] = self.children[i].strip_scope_analysis()
+ return self
@method(ItemList)
def strip_scope_analysis(self):
self.scope = None
- Node.strip_scope_analysis(self)
+ return Node.strip_scope_analysis(self)
@method(EnumSpecifier)
def strip_scope_analysis(self):
self.scope_tag = None
- Specifier.strip_scope_analysis(self)
+ return Specifier.strip_scope_analysis(self)
@method(ExpressionIdentifier)
def strip_scope_analysis(self):
self.scope_identifier = None
- Expression.strip_scope_analysis(self)
+ return Expression.strip_scope_analysis(self)
@method(FunctionDefinition)
def strip_scope_analysis(self):
self.scope_identifier = None
- Node.strip_scope_analysis(self)
+ return Node.strip_scope_analysis(self)
@method(Identifier)
def strip_scope_analysis(self):
self.scope_identifier = None
- Node.strip_scope_analysis(self)
+ return Node.strip_scope_analysis(self)
@method(InitDeclarator)
def strip_scope_analysis(self):
self.scope_identifier = None
- Node.strip_scope_analysis(self)
+ return Node.strip_scope_analysis(self)
@method(ParameterDeclaration)
def strip_scope_analysis(self):
self.scope_identifier = None
- Node.strip_scope_analysis(self)
+ return Node.strip_scope_analysis(self)
@method(StructSpecifier)
def strip_scope_analysis(self):
self.scope_tag = None
- Specifier.strip_scope_analysis(self)
+ return Specifier.strip_scope_analysis(self)
@method(TagIdentifier)
def strip_scope_analysis(self):
self.scope_tag = None
- Node.strip_scope_analysis(self)
+ return Node.strip_scope_analysis(self)
@method(TypedefName)
def strip_scope_analysis(self):
self.scope_identifier = None
- Specifier.strip_scope_analysis(self)
+ return Specifier.strip_scope_analysis(self)
@method(UnionSpecifier)
def strip_scope_analysis(self):
self.scope_tag = None
- Specifier.strip_scope_analysis(self)
+ return Specifier.strip_scope_analysis(self)
+@method(ExpressionCast)
+def strip_scope_analysis(self):
+ # not really scope analysis but strip casts that were not in the original
+ Expression.strip_scope_analysis(self)
+ if len(self.children[0].children) == 0:
+ return self.children[1]
+ return self
+del strip_scope_analysis
+
+# deserializing the tree creates new copies of primitive types
+# this can waste space if the tree is subsequently modified using
+# primitive types defined in this file -- fix deserialized tree
+@method(Type)
+def fix_type_sharing(self):
+ return self
+@method(TypeVoid)
+def fix_type_sharing(self):
+ return type_void
+@method(TypeBool)
+def fix_type_sharing(self):
+ return type_bool
+@method(TypeInt)
+def fix_type_sharing(self):
+ return rank_to_type[self.rank]
+@method(TypeFloat)
+def fix_type_sharing(self):
+ return rank_to_type[self.rank]
+@method(TypePointer)
+def fix_type_sharing(self):
+ self.target_type = self.target_type.fix_type_sharing()
+ return Type.fix_type_sharing(self)
+@method(TypeArray)
+def fix_type_sharing(self):
+ self.element_type = self.element_type.fix_type_sharing()
+ return Type.fix_type_sharing(self)
+@method(TypeFunction)
+def fix_type_sharing(self):
+ self.return_type = self.return_type.fix_type_sharing()
+ return Type.fix_type_sharing(self)
+@method(TypeFunctionANSI)
+def fix_type_sharing(self):
+ for i in range(len(self.formal_parameters)):
+ self.formal_parameters[i] = self.formal_parameters[i].fix_type_sharing()
+ return TypeFunction.fix_type_sharing(self)
+@method(TypeStructOrUnion)
+def fix_type_sharing(self):
+ for i in self.members:
+ i.fix_type_sharing()
+ return Type.fix_type_sharing(self)
+@method(TypeEnum)
+def fix_type_sharing(self):
+ # avoid calling TypeSignedInt.fix_type_sharing() which replaces us by rank
+ return self
+del fix_type_sharing
+
+@method(TypeStructOrUnion.Member)
+def fix_type_sharing(self):
+ self.type = self.type.fix_type_sharing()
+del fix_type_sharing
+
+@method(Scope)
+def fix_type_sharing(self):
+ for i in self.identifiers.values():
+ i.fix_type_sharing()
+ for i in self.struct_tags.values():
+ i.fix_type_sharing()
+ for i in self.union_tags.values():
+ i.fix_type_sharing()
+ for i in self.enum_tags.values():
+ i.fix_type_sharing()
+del fix_type_sharing
+
+@method(Scope.Identifier)
+def fix_type_sharing(self):
+ self.type = self.type.fix_type_sharing()
+del fix_type_sharing
+
+@method(Scope.Tag)
+def fix_type_sharing(self):
+ self.type = self.type.fix_type_sharing()
+del fix_type_sharing
+
+@method(Node)
+def fix_type_sharing(self):
+ for i in range(len(self.children)):
+ self.children[i].fix_type_sharing()
+@method(ItemList)
+def fix_type_sharing(self):
+ self.scope.fix_type_sharing()
+ Node.fix_type_sharing(self)
+@method(Expression)
+def fix_type_sharing(self):
+ self.type = self.type.fix_type_sharing()
+ Node.fix_type_sharing(self)
+@method(Initializer)
+def fix_type_sharing(self):
+ self.type = self.type.fix_type_sharing()
+ Node.fix_type_sharing(self)
+@method(DesignatorInitializer)
+def fix_type_sharing(self):
+ self.type = self.type.fix_type_sharing()
+ Node.fix_type_sharing(self)
+@method(MemberIdentifier)
+def fix_type_sharing(self):
+ self.type = self.type.fix_type_sharing()
+ Node.fix_type_sharing(self)
+@method(ParameterDeclaration)
+def fix_type_sharing(self):
+ self.type = self.type.fix_type_sharing()
+ Node.fix_type_sharing(self)
+@method(TypeName)
+def fix_type_sharing(self):
+ self.type = self.type.fix_type_sharing()
+ Node.fix_type_sharing(self)
assert False
expression_identifier.calc_type()
- #expression_identifier.calc_value()
+ expression_identifier.calc_value()
}
| constant
| STRING_LITERAL
rank = actual_parameters.children[i].type.rank
if rank >= 0 and rank < t_def.INT_RANK:
actual_parameters.children[i] = t_def.add_cast(
- base_type.type_signed_int,
+ t_def.type_signed_int,
actual_parameters.children[i]
)
elif rank >= t_def.FLOAT_RANK and rank < t_def.DOUBLE_RANK:
actual_parameters.children[i] = t_def.add_cast(
- base_type.rank_to_type[rank + t_def.DOUBLE_RANK - t_def.FLOAT_RANK],
+ t_def.rank_to_type[rank + t_def.DOUBLE_RANK - t_def.FLOAT_RANK],
actual_parameters.children[i]
)
}
/* occurs in array declarator */
assignment_expression_or_asterisk_opt
- : %space (?E{t_def.ExpressionEmpty})
+ : %space (?E{build, t_def.ExpressionEmpty})
| %space (?E{t_def.ExpressionAsterisk}'*')
| assignment_expression {
container = yy_element_stack[-1]
assert isinstance(container.children[0], t_def.Expression)
- if container.children[0].type != base_type.type_size_t:
+ if container.children[0].type != t_def.type_size_t:
container.children[0] = t_def.add_cast(
- base_type.type_size_t,
+ t_def.type_size_t,
container.children[0]
)
}
| '=' constant_expression {
container = yy_element_stack[-1]
assert isinstance(container.children[0], t_def.Expression)
- if container.children[0].type != base_type.type_signed_int:
+ if container.children[0].type != t_def.type_signed_int:
container.children[0] = t_def.add_cast(
- base_type.type_signed_int,
+ t_def.type_signed_int,
container.children[0]
)
}
declaration_specifier_list = yy_element_stack[-1].children[0]
- assert(not doing_typedef)
+ assert not doing_typedef
for i in declaration_specifier_list.children:
if (
isinstance(i, t_def.StorageClassSpecifier) and
):
storage_class1 = t_def.STORAGE_CLASS_AUTO
- align_m1 = _type.align - 1
- scope.size = (scope.size + align_m1) & ~align_m1
- scope_identifier.offset = scope.size
- if _type.size >= 0: # unknown size treated as 0 bytes (not correct!!)
- scope.size += _type.size
+ # don't do this here -- we don't have size of indeterminate array yet
+ #align_m1 = _type.align - 1
+ #scope.size = (scope.size + align_m1) & ~align_m1
+ #scope_identifier.offset = scope.size
+ #if _type.size >= 0: # unknown size treated as 0 bytes (not correct!!)
+ # scope.size += _type.size
+ elif storage_class1 == t_def.STORAGE_CLASS_TYPEDEF: # TEMPORARY
+ assert not scope_identifier.defined # TEMPORARY
+ scope_identifier.defined = True # TEMPORARY
if storage_class1 == t_def.STORAGE_CLASS_NONE:
pass
t_def.STORAGE_CLASS_TYPEDEF
}:
assert len(init_declarator.children) < 2 # can t have initializer
- elif (
- isinstance(_type, t_def.TypeArray) and
- _type.element_count == -1 and
- len(init_declarator.children) >= 2
- ):
- # size of indeterminate sized array can be deduced from initializer
- element_size = _type.element_type.size
- assert element_size >= 0 # must be of determinate size
- _type.size = max_index * element_size
- _type.element_count = max_index
else:
+ if (
+ isinstance(_type, t_def.TypeArray) and
+ _type.element_count == -1 and
+ len(init_declarator.children) >= 2
+ ):
+ # size of indeterminate sized array can be deduced from initializer
+ element_size = _type.element_type.size
+ assert element_size >= 0 # must be of determinate size
+ _type.size = max_index * element_size
+ _type.element_count = max_index
+
assert _type.size >= 0 # must be of determinate size
+ align_m1 = _type.align - 1
+ scope.size = (scope.size + align_m1) & ~align_m1
+ scope_identifier.offset = scope.size
+ scope.size += _type.size
}
;
_type = scope_tag.type
else:
_type = t_def.TypeStruct()
- scope_tag = t_def.Scope.Tag(type = _type)
+ scope_tag = t_def.Scope.Tag(name = name, type = _type)
scope.struct_tags[name] = scope_tag
struct_specifier.scope_tag = scope_tag
)
size += member_type.size
align = max(align, member_type.align)
+
+ # make the size a multiple of the alignment
+ align_m1 = align - 1
+ size = (size + align_m1) & ~align_m1
+
_type.size = size
_type.align = align
_type.members = members
i = i.enclosing_scope
else:
_type = t_def.TypeStruct()
- scope_tag = t_def.Scope.Tag(type = _type)
+ scope_tag = t_def.Scope.Tag(name = name, type = _type)
scope.struct_tags[name] = scope_tag
struct_specifier.scope_tag = scope_tag
}
_type = scope_tag.type
else:
_type = t_def.TypeUnion()
- scope_tag = t_def.Scope.Tag(type = _type)
+ scope_tag = t_def.Scope.Tag(name = name, type = _type)
scope.union_tags[name] = scope_tag
union_specifier.scope_tag = scope_tag
)
size = max(size, member_type.size)
align = max(align, member_type.align)
+
+ # make the size a multiple of the alignment
+ align_m1 = align - 1
+ size = (size + align_m1) & ~align_m1
+
_type.size = size
_type.align = align
_type.members = members
i = i.enclosing_scope
else:
_type = t_def.TypeUnion()
- scope_tag = t_def.Scope.Tag(type = _type)
+ scope_tag = t_def.Scope.Tag(name = name, type = _type)
scope.union_tags[name] = scope_tag
union_specifier.scope_tag = scope_tag
}
struct_declarator
: %space (?E{t_def.StructDeclarator}declarator_opt ':' constant_expression) {
struct_declarator = yy_element_stack[-1].children[0]
- if struct_declarator.children[1].type != base_type.type_signed_int:
+ if struct_declarator.children[1].type != t_def.type_signed_int:
struct_declarator.children[1] = t_def.add_cast(
- base_type.type_signed_int,
+ t_def.type_signed_int,
struct_declarator.children[1]
)
}
size = t_def.INT_SIZE,
align = t_def.INT_ALIGN
)
- scope_tag = t_def.Scope.Tag(type = _type)
+ scope_tag = t_def.Scope.Tag(name = name, type = _type)
scope.enum_tags[name] = scope_tag
enum_specifier.scope_tag = scope_tag
assert member_name not in members
if len(i.children) >= 2:
expression = i.children[1]
- assert expression.type == base_type.type_signed_int
+ assert expression.type == t_def.type_signed_int
assert isinstance(expression.value, t_def.ValueInt)
value = expression.value.value
members[member_name] = t_def.TypeEnum.Member(
size = t_def.INT_SIZE,
align = t_def.INT_ALIGN
)
- scope_tag = t_def.Scope.Tag(type = _type)
+ scope_tag = t_def.Scope.Tag(name = name, type = _type)
scope.enum_tags[name] = scope_tag
enum_specifier.scope_tag = scope_tag
}
: %space (?E{t_def.AlignAsType}ALIGNAS '(' type_name ')')
| %space (?E{t_def.AlignAsExpression}ALIGNAS '(' constant_expression ')') {
align_as_expression = yy_element_stack[-1].children[0]
- if align_as_expression.children[0].type != base_type.type_size_t:
+ if align_as_expression.children[0].type != t_def.type_size_t:
align_as_expression.children[0] = t_def.add_cast(
- base_type.type_size_t,
+ t_def.type_size_t,
align_as_expression.children[0]
)
}
initializer_array_or_struct = yy_element_stack[-1].children[0]
initializer_array_or_struct.type = initializer_stack[-1][0]
}
- | (?E{t_def.InitializerExpression}assignment_expression) {
+ | %space (?E{t_def.InitializerExpression}assignment_expression) {
initializer_expression = yy_element_stack[-1].children[0]
if initializer_expression.children[0].type != initializer_stack[-1][0]:
initializer_expression.children[0] = t_def.add_cast(
# get numeric index from designator
expression = i.children[0]
- assert expression.type == base_type.type_ssize_t
+ assert expression.type == t_def.type_ssize_t
assert isinstance(expression.value, t_def.ValueInt)
j = expression.value.value
designator
: %space (?E{t_def.DesignatorIndex}'[' constant_expression ']') {
designator_index = yy_element_stack[-1].children[0]
- if designator_index.children[0].type != base_type.type_ssize_t:
+ if designator_index.children[0].type != t_def.type_ssize_t:
designator_index.children[0] = t_def.add_cast(
- base_type.type_ssize_t,
+ t_def.type_ssize_t,
designator_index.children[0]
)
}
static_assert_declaration
: %space (?E{t_def.StaticAssertDeclaration}STATIC_ASSERT '(' constant_expression ',' STRING_LITERAL ')' ';') {
static_assert_declaration = yy_element_stack[-1].children[0]
- if static_assert_declaration.children[0].type != base_type.type_bool:
+ if static_assert_declaration.children[0].type != t_def.type_bool:
static_assert_declaration.children[0] = t_def.add_cast(
- base_type.type_bool,
+ t_def.type_bool,
static_assert_declaration.children[0]
)
}
statement_expression = yy_element_stack[-1].children[0]
if not isinstance(statement_expression.children[0].type, t_def.TypeVoid):
statement_expression.children[0] = t_def.add_cast(
- base_type.type_void,
+ t_def.type_void,
statement_expression.children[0]
)
}
statement_if_else = yy_element_stack[-1].children[0]
if not isinstance(statement_if_else.children[0].type, t_def.TypeBool):
statement_if_else.children[0] = t_def.add_cast(
- base_type.type_bool,
+ t_def.type_bool,
statement_if_else.children[0]
)
}
statement_if = yy_element_stack[-1].children[0]
if not isinstance(statement_if.children[0].type, t_def.TypeBool):
statement_if.children[0] = t_def.add_cast(
- base_type.type_bool,
+ t_def.type_bool,
statement_if.children[0]
)
}
statement_while = yy_element_stack[-1].children[0]
if not isinstance(statement_while.children[0].type, t_def.TypeBool):
statement_while.children[0] = t_def.add_cast(
- base_type.type_bool,
+ t_def.type_bool,
statement_while.children[0]
)
}
statement_do_while = yy_element_stack[-1].children[0]
if not isinstance(statement_do_while.children[1].type, t_def.TypeBool):
statement_do_while.children[1] = t_def.add_cast(
- base_type.type_bool,
+ t_def.type_bool,
statement_do_while.children[1]
)
}
statement_expression = statement_for.children[0]
if not isinstance(statement_expression.children[0].type, t_def.TypeVoid):
statement_expression.children[0] = t_def.add_cast(
- base_type.type_void,
+ t_def.type_void,
statement_expression.children[0]
)
if not isinstance(statement_for.children[1].type, t_def.TypeBool):
statement_for.children[1] = t_def.add_cast(
- base_type.type_bool,
+ t_def.type_bool,
statement_for.children[1]
)
if not isinstance(statement_for.children[2].type, t_def.TypeVoid):
statement_for.children[2] = t_def.add_cast(
- base_type.type_void,
+ t_def.type_void,
statement_for.children[2]
)
}
statement_for = yy_element_stack[-1].children[0]
if not isinstance(statement_for.children[1].type, t_def.TypeBool):
statement_for.children[1] = t_def.add_cast(
- base_type.type_bool,
+ t_def.type_bool,
statement_for.children[1]
)
if not isinstance(statement_for.children[2].type, t_def.TypeVoid):
statement_for.children[2] = t_def.add_cast(
- base_type.type_void,
+ t_def.type_void,
statement_for.children[2]
)
}
import t_def
-# primitive types
-type_void = t_def.TypeVoid(size = 0)
-type_bool = t_def.TypeBool(rank = 0, size = 1)
-type_signed_char = t_def.TypeIntSigned(rank = 1, size = 1)
-type_unsigned_char = t_def.TypeIntUnsigned(rank = 2, size = 1)
-type_signed_short = t_def.TypeIntSigned(rank = 3, size = 2, align = 2)
-type_unsigned_short = t_def.TypeIntUnsigned(rank = 4, size = 2, align = 2)
-type_signed_int = t_def.TypeIntSigned(rank = 5, size = 4, align = 4)
-type_unsigned_int = t_def.TypeIntUnsigned(rank = 6, size = 4, align = 4)
-type_signed_long = t_def.TypeIntSigned(rank = 7, size = 8, align = 8)
-type_unsigned_long = t_def.TypeIntUnsigned(rank = 8, size = 8, align = 8)
-type_signed_long_long = t_def.TypeIntSigned(rank = 9, size = 16, align = 16)
-type_unsigned_long_long = t_def.TypeIntUnsigned(rank = 10, size = 16, align = 16)
-type_float = t_def.TypeFloat(rank = 11, size = 4, align = 4)
-type_float_imaginary = t_def.TypeFloatImaginary(rank = 12, size = 4, align = 4)
-type_float_complex = t_def.TypeFloatComplex(rank = 13, size = 8, align = 4)
-type_double = t_def.TypeFloat(rank = 14, size = 8, align = 8)
-type_double_imaginary = t_def.TypeFloatImaginary(rank = 15, size = 8, align = 8)
-type_double_complex = t_def.TypeFloatComplex(rank = 16, size = 16, align = 8)
-type_long_double = t_def.TypeFloat(rank = 17, size = 16, align = 16)
-type_long_double_imaginary = t_def.TypeFloatImaginary(rank = 18, size = 16, align = 16)
-type_long_double_complex = t_def.TypeFloatComplex(rank = 19, size = 32, align = 16)
-
-type_ssize_t = type_signed_int
-assert type_ssize_t.size == t_def.POINTER_SIZE
-type_size_t = type_unsigned_int
-assert type_size_t.size == t_def.POINTER_SIZE
-
-rank_to_type = [
- type_bool, # 0
- type_signed_char, # 1
- type_unsigned_char, # 2
- type_signed_short, # 3
- type_unsigned_short, # 4
- type_signed_int, # 5
- type_unsigned_int, # 6
- type_signed_long, # 7
- type_unsigned_long, # 8
- type_signed_long_long, # 9
- type_unsigned_long_long, # 10
- type_float, # 11
- type_float_imaginary, # 12
- type_float_complex, # 13
- type_double, # 14
- type_double_imaginary, # 15
- type_double_complex, # 16
- type_long_double, # 17
- type_long_double_imaginary, # 18
- type_long_double_complex # 19
-]
-
-# this is not correct -- check standard
-# minimum rank, maximum rank, promoted rank
-complex_promotions = {
- (11, 12): 13, # float, float imaginary -> float complex
- (11, 15): 16, # float, double imaginary -> double complex
- (11, 18): 19, # float, long double imaginary -> long double complex
- (14, 15): 16, # double, double imaginary -> double complex
- (14, 18): 19, # double, long double imaginary -> long double complex
- (17, 18): 19 # long double, long double imaginary -> long double complex
-}
-
# void char short int long float double signed unsigned bool imaginary complex
type_specifiers_to_type = {
- (1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0): type_void,
- (0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0): type_signed_char,
- (0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0): type_signed_char,
- (0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0): type_unsigned_char,
- (0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0): type_signed_short,
- (0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0): type_signed_short,
- (0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0): type_unsigned_short,
- (0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0): type_signed_short,
- (0, 0, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0): type_signed_short,
- (0, 0, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0): type_unsigned_short,
- (0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0): type_signed_int,
- (0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0): type_signed_int,
- (0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0): type_unsigned_int,
- (0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0): type_signed_int,
- (0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0): type_signed_int,
- (0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0): type_unsigned_int,
- (0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0): type_signed_long,
- (0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0): type_signed_long,
- (0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0): type_unsigned_long,
- (0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0): type_signed_long,
- (0, 0, 0, 1, 1, 0, 0, 1, 0, 0, 0, 0): type_signed_long,
- (0, 0, 0, 1, 1, 0, 0, 0, 1, 0, 0, 0): type_unsigned_long,
- (0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0): type_signed_long_long,
- (0, 0, 0, 0, 2, 0, 0, 1, 0, 0, 0, 0): type_signed_long_long,
- (0, 0, 0, 0, 2, 0, 0, 0, 1, 0, 0, 0): type_unsigned_long_long,
- (0, 0, 0, 1, 2, 0, 0, 0, 0, 0, 0, 0): type_signed_long_long,
- (0, 0, 0, 1, 2, 0, 0, 1, 0, 0, 0, 0): type_signed_long_long,
- (0, 0, 0, 1, 2, 0, 0, 0, 1, 0, 0, 0): type_unsigned_long_long,
- (0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0): type_float,
- (0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0): type_float_imaginary,
- (0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1): type_float_complex,
- (0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0): type_double,
- (0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0): type_double_imaginary,
- (0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1): type_double_complex,
- (0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0): type_long_double,
- (0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 1, 0): type_long_double_imaginary,
- (0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 1): type_long_double_complex,
- (0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0): type_bool
+ (1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0): t_def.type_void,
+ (0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0): t_def.type_signed_char,
+ (0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0): t_def.type_signed_char,
+ (0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0): t_def.type_unsigned_char,
+ (0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0): t_def.type_signed_short,
+ (0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0): t_def.type_signed_short,
+ (0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0): t_def.type_unsigned_short,
+ (0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0): t_def.type_signed_short,
+ (0, 0, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0): t_def.type_signed_short,
+ (0, 0, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0): t_def.type_unsigned_short,
+ (0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0): t_def.type_signed_int,
+ (0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0): t_def.type_signed_int,
+ (0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0): t_def.type_unsigned_int,
+ (0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0): t_def.type_signed_int,
+ (0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0): t_def.type_signed_int,
+ (0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0): t_def.type_unsigned_int,
+ (0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0): t_def.type_signed_long,
+ (0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0): t_def.type_signed_long,
+ (0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0): t_def.type_unsigned_long,
+ (0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0): t_def.type_signed_long,
+ (0, 0, 0, 1, 1, 0, 0, 1, 0, 0, 0, 0): t_def.type_signed_long,
+ (0, 0, 0, 1, 1, 0, 0, 0, 1, 0, 0, 0): t_def.type_unsigned_long,
+ (0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0): t_def.type_signed_long_long,
+ (0, 0, 0, 0, 2, 0, 0, 1, 0, 0, 0, 0): t_def.type_signed_long_long,
+ (0, 0, 0, 0, 2, 0, 0, 0, 1, 0, 0, 0): t_def.type_unsigned_long_long,
+ (0, 0, 0, 1, 2, 0, 0, 0, 0, 0, 0, 0): t_def.type_signed_long_long,
+ (0, 0, 0, 1, 2, 0, 0, 1, 0, 0, 0, 0): t_def.type_signed_long_long,
+ (0, 0, 0, 1, 2, 0, 0, 0, 1, 0, 0, 0): t_def.type_unsigned_long_long,
+ (0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0): t_def.type_float,
+ (0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0): t_def.type_float_imaginary,
+ (0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1): t_def.type_float_complex,
+ (0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0): t_def.type_double,
+ (0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0): t_def.type_double_imaginary,
+ (0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1): t_def.type_double_complex,
+ (0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0): t_def.type_long_double,
+ (0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 1, 0): t_def.type_long_double_imaginary,
+ (0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 1): t_def.type_long_double_complex,
+ (0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0): t_def.type_bool
}
@t_def.method(t_def.SpecifierList)
import base_type
import t_def
+# this is not correct -- check standard
+# minimum rank, maximum rank, promoted rank
+complex_promotions = {
+ (11, 12): 13, # float, float imaginary -> float complex
+ (11, 15): 16, # float, double imaginary -> double complex
+ (11, 18): 19, # float, long double imaginary -> long double complex
+ (14, 15): 16, # double, double imaginary -> double complex
+ (14, 18): 19, # double, long double imaginary -> long double complex
+ (17, 18): 19 # long double, long double imaginary -> long double complex
+}
+
# f l
floating_suffix_to_type = {
- (0, 0): base_type.type_double,
- (1, 0): base_type.type_float,
- (0, 1): base_type.type_long_double
+ (0, 0): t_def.type_double,
+ (1, 0): t_def.type_float,
+ (0, 1): t_def.type_long_double
}
# u l ll
integer_suffix_to_type = {
- (0, 0, 0): base_type.type_signed_int,
- (1, 0, 0): base_type.type_unsigned_int,
- (0, 1, 0): base_type.type_signed_long,
- (1, 1, 0): base_type.type_unsigned_long,
- (0, 0, 1): base_type.type_signed_long_long,
- (1, 0, 1): base_type.type_unsigned_long_long
+ (0, 0, 0): t_def.type_signed_int,
+ (1, 0, 0): t_def.type_unsigned_int,
+ (0, 1, 0): t_def.type_signed_long,
+ (1, 1, 0): t_def.type_unsigned_long,
+ (0, 0, 1): t_def.type_signed_long_long,
+ (1, 0, 1): t_def.type_unsigned_long_long
}
def add_cast(_type, expression):
rank = self.children[0].type.rank
assert rank >= 0 # pointers, etc are not handled yet
promoted_rank = max(rank, t_def.INT_RANK)
- promoted_type = base_type.rank_to_type[promoted_rank]
+ promoted_type = t_def.rank_to_type[promoted_rank]
if rank < promoted_rank:
self.children[0] = add_cast(promoted_type, self.children[0])
self.type = promoted_type
@t_def.method(t_def.ExpressionUnaryLogical)
def calc_type(self):
- if self.children[0].type != base_type.type_bool:
- self.children[0] = add_cast(base_type.type_bool, self.children[0])
- self.type = base_type.type_bool
+ if self.children[0].type != t_def.type_bool:
+ self.children[0] = add_cast(t_def.type_bool, self.children[0])
+ self.type = t_def.type_bool
@t_def.method(t_def.ExpressionBinaryArithmeticOrCompareOrLogical)
def calc_type(self):
rank0 = self.children[0].type.rank
min_rank = min(rank0, rank1)
assert min_rank >= 0 # pointers, etc are not handled yet
max_rank = max(rank0, rank1)
- promoted_rank = base_type.complex_promotions.get(
+ promoted_rank = complex_promotions.get(
(min_rank, max_rank),
max(max_rank, t_def.INT_RANK)
)
- promoted_type = base_type.rank_to_type[promoted_rank]
+ promoted_type = t_def.rank_to_type[promoted_rank]
if rank0 < promoted_rank:
self.children[0] = add_cast(promoted_type, self.children[0])
if rank1 < promoted_rank:
type0 = self.children[0].type
type1 = self.children[1].type
if isinstance(type0, t_def.TypePointer) and isinstance(type1, t_def.TypeInt):
- if type1 != base_type.type_ssize_t:
- self.children[1] = add_cast(base_type.type_ssize_t, self.children[1])
+ if type1 != t_def.type_ssize_t:
+ self.children[1] = add_cast(t_def.type_ssize_t, self.children[1])
self.type = type0
elif isinstance(type0, t_def.TypeInt) and isinstance(type1, t_def.TypePointer):
- if type0 != base_type.type_ssize_t:
- self.children[0] = add_cast(base_type.type_ssize_t, self.children[0])
+ if type0 != t_def.type_ssize_t:
+ self.children[0] = add_cast(t_def.type_ssize_t, self.children[0])
self.type = type1
else:
t_def.ExpressionBinaryArithmeticOrCompareOrLogical.calc_type(self)
type0 = self.children[0].type
type1 = self.children[1].type
if isinstance(type0, t_def.TypePointer) and isinstance(type1, t_def.TypeInt):
- if type1 != base_type.type_ssize_t:
- self.children[1] = add_cast(base_type.type_ssize_t, self.children[1])
+ if type1 != t_def.type_ssize_t:
+ self.children[1] = add_cast(t_def.type_ssize_t, self.children[1])
self.type = type0
elif isinstance(type0, t_def.TypePointer) and isinstance(type1, t_def.TypePointer):
- self.type = base_type.type_ssize_t
+ self.type = t_def.type_ssize_t
else:
t_def.ExpressionBinaryArithmeticOrCompareOrLogical.calc_type(self)
@t_def.method(t_def.ExpressionBinaryCompare)
pass
else:
t_def.ExpressionBinaryArithmeticOrCompareOrLogical.calc_type(self)
- self.type = base_type.type_bool
+ self.type = t_def.type_bool
@t_def.method(t_def.ExpressionBinaryLogical)
def calc_type(self):
- self.type = base_type.type_bool
- if self.children[0].type != base_type.type_bool:
- self.children[0] = add_cast(base_type.type_bool, self.children[0])
- if self.children[1].type != base_type.type_bool:
- self.children[1] = add_cast(base_type.type_bool, self.children[1])
+ self.type = t_def.type_bool
+ if self.children[0].type != t_def.type_bool:
+ self.children[0] = add_cast(t_def.type_bool, self.children[0])
+ if self.children[1].type != t_def.type_bool:
+ self.children[1] = add_cast(t_def.type_bool, self.children[1])
@t_def.method(t_def.ExpressionArrayOrStruct)
def calc_type(self):
self.type = self.children[0].type
)
@t_def.method(t_def.ExpressionAlignOfType)
def calc_type(self):
- self.type = base_type.type_size_t
+ self.type = t_def.type_size_t
@t_def.method(t_def.ExpressionArrayOrStruct)
def calc_type(self):
self.type = t_def.array_decay(self.children[0].type)
self.type = self.children[0].type
@t_def.method(t_def.ExpressionCharacterConstant)
def calc_type(self):
- self.type = base_type.type_signed_int
+ self.type = t_def.type_signed_int
@t_def.method(t_def.ExpressionComma)
def calc_type(self):
if not isinstance(self.children[0].type, t_def.TypeVoid):
self.children[0] = add_cast(
- base_type.type_void,
+ t_def.type_void,
self.children[0]
)
self.type = self.children[1].type
@t_def.method(t_def.ExpressionConditional)
def calc_type(self):
- if self.children[0].type != base_type.type_bool:
- self.children[0] = add_cast(base_type.type_bool, self.children[0])
+ if self.children[0].type != t_def.type_bool:
+ self.children[0] = add_cast(t_def.type_bool, self.children[0])
rank1 = self.children[1].type.rank
rank2 = self.children[2].type.rank
min_rank = min(rank1, rank2)
assert min_rank >= 0 # pointers, etc are not handled yet
max_rank = max(rank1, rank2)
- max_type = base_type.rank_to_type[max_rank]
+ max_type = t_def.rank_to_type[max_rank]
if rank1 < max_rank:
self.children[1] = add_cast(max_type, self.children[1])
if rank2 < max_rank:
self.type = t_def.array_decay(pointer_type.target_type)
@t_def.method(t_def.ExpressionEmpty)
def calc_type(self):
- self.type = base_type.type_void
+ self.type = t_def.type_void
@t_def.method(t_def.ExpressionMember)
def calc_type(self):
struct_or_union_type = self.children[0].type
def calc_type(self):
pointer_type = self.children[0].type
assert isinstance(pointer_type, t_def.TypePointer)
- if self.children[1].type != base_type.type_ssize_t:
- self.children[1] = add_cast(base_type.type_ssize_t, self.children[1])
+ if self.children[1].type != t_def.type_ssize_t:
+ self.children[1] = add_cast(t_def.type_ssize_t, self.children[1])
self.type = t_def.array_decay(pointer_type.target_type)
@t_def.method(t_def.ExpressionIntegerConstant)
def calc_type(self):
self.type = integer_suffix_to_type[tuple(integer_suffix)]
@t_def.method(t_def.ExpressionSizeOfExpression)
def calc_type(self):
- self.type = base_type.type_size_t
+ self.type = t_def.type_size_t
@t_def.method(t_def.ExpressionSizeOfType)
def calc_type(self):
- self.type = base_type.type_size_t
+ self.type = t_def.type_size_t
@t_def.method(t_def.ExpressionStringLiteral)
def calc_type(self):
self.type = t_def.TypePointer(
size = t_def.POINTER_SIZE,
align = t_def.POINTER_ALIGN,
- target_type = base_type.type_signed_char
+ target_type = t_def.type_signed_char
)
del calc_type
self.type.size * 8,
isinstance(self.type, t_def.TypeIntUnsigned)
)
- elif isinstance(self.type, t_def.TypeFloat):
+ elif isinstance(self.type, t_def.TypeFloatReal):
assert isinstance(value, t_def.ValueFloat)
self.value = float_value(
self.operate_float(value.value),
self.type.size * 8,
isinstance(self.type, t_def.TypeIntUnsigned)
)
- elif isinstance(self.type, t_def.TypeFloat):
+ elif isinstance(self.type, t_def.TypeFloatReal):
assert isinstance(value0, t_def.ValueFloat)
assert isinstance(value1, t_def.ValueFloat)
self.value = float_value(
self.value = bool_value(
self.operate_relational_int(value0.value, value1.value)
)
- elif isinstance(type0, t_def.TypeFloat) and isinstance(type1, t_def.TypeFloat):
+ elif isinstance(type0, t_def.TypeFloatReal) and isinstance(type1, t_def.TypeFloatReal):
assert isinstance(value0, t_def.ValueFloat)
assert isinstance(value1, t_def.ValueFloat)
self.value = bool_value(
self.type.size * 8,
isinstance(self.type, t_def.TypeIntUnsigned)
)
- elif isinstance(self.type, t_def.TypeFloat):
+ elif isinstance(self.type, t_def.TypeFloatReal):
self.value = float_value(
gmpy2.mpfr(from_value.value),
self.type.size * 8
)
# other from_type is not handled yet
- elif isinstance(from_type, t_def.TypeFloat):
+ elif isinstance(from_type, t_def.TypeFloatReal):
assert isinstance(from_value, t_def.ValueFloat)
if isinstance(self.type, t_def.TypeBool):
self.value = bool_value(int(bool(from_value.value)))
self.type.size * 8,
isinstance(self.type, t_def.TypeIntUnsigned)
)
- elif isinstance(self.type, t_def.TypeFloat):
+ elif isinstance(self.type, t_def.TypeFloatReal):
self.value = float_value(
from_value.value,
self.type.size * 8
if isinstance(expression, t_def.ExpressionEmpty):
element_count = -1
else:
- assert expression.type == base_type.type_size_t
+ assert expression.type == t_def.type_size_t
assert isinstance(expression.value, t_def.ValueInt)
element_count = expression.value.value
return self.children[0].get_name_and_type(
int align = 1;
};
class TypeVoid: Type;
+class TypeBool: Type;
class TypeInt: Type;
class TypeIntSigned: TypeInt;
class TypeEnum: TypeIntSigned {
};
class TypeIntUnsigned: TypeInt;
class TypeFloat: Type;
-class TypeFloat: TypeFloat;
+class TypeFloatReal: TypeFloat;
class TypeFloatImaginary: TypeFloat;
class TypeFloatComplex: TypeFloat;
-class TypeBool: Type;
class TypePointer: Type {
ref target_type;
};
]
}
-float_size_to_specifiers = {
+float_real_size_to_specifiers = {
4: [
TYPE_SPECIFIER_FLOAT
],
TypeSpecifier(n = i)
for i in unsigned_int_size_to_specifiers[self.size]
]
-@method(TypeFloat)
+@method(TypeFloatReal)
def get_type_specifiers(self, scope):
return [
TypeSpecifier(n = i)
- for i in float_size_to_specifiers[self.size]
+ for i in float_real_size_to_specifiers[self.size]
]
@method(TypeFloatImaginary)
def get_type_specifiers(self, scope):
declarator = init_declarator.children[0]
# if it's function, allow multiple definition
- is_function = t_def.get_declarator_function(
+ declarator_function = t_def.get_declarator_function(
declarator
- ) is not None
+ )
+ is_function = (
+ declarator_function is not None and
+ isinstance(declarator_function.children[0], t_def.DeclaratorIdentifier)
+ )
declarator_identifier = t_def.get_declarator_identifier(
declarator
self.children[1]
)
assert declarator_function is not None
-
- declarator_identifier = t_def.get_declarator_identifier(
- declarator_function
- )
- assert declarator_identifier is not None
+ declarator_identifier = declarator_function.children[0]
+ assert isinstance(declarator_identifier, t_def.DeclaratorIdentifier)
# add the function being defined to the enclosing scope
name = declarator_identifier.text[0]
print('scope analysis: parameter:', parameter_name)
assert parameter_name not in new_scope.identifiers
parameter_declarator_identifier.scope_identifier = (
- t_def.Scope.Identifier(name = parameter_name)
+ t_def.Scope.Identifier(
+ name = parameter_name,
+ defined = True
+ )
)
new_scope.identifiers[parameter_name] = (
parameter_declarator_identifier.scope_identifier
parameter_name = parameter_identifier.text[0]
assert parameter_name not in new_scope.identifiers
parameter_identifier.scope_identifier = t_def.Scope.Identifier(
- name = parameter_name
+ name = parameter_name,
+ defined = True
)
new_scope.identifiers[parameter_name] = (
parameter_identifier.scope_identifier
import calc_value
import t_def
-def add_cast(_type, expression):
- if expression.type != _type:
- # wrapping a node hides the wrapped node from value analysis
- # strictly speaking, the type analysis should not be mixed with
- # the value analysis, but it is more pragmatic to cheat a little
- expression.calc_value()
-
- expression = ExpressionCast(
- children = [TypeName(type = _type), expression]
- )
- return expression
-
# in a few special cases (function header followed by body, declarator
# followed by initializer) the ordinary post-order type analysis is not
# sufficient and we need to intervene in the middle of the rule to do
# fill in the formal parameters in the inner scope
new_scope = self.children[3].scope
- new_scope.size = 0
if isinstance(declarator_function, t_def.DeclaratorFunctionANSI):
parameter_declaration_list = declarator_function.children[1]
if not t_def.parameter_declaration_list_is_void(
parameter_declaration_list
):
- for parameter_declaration in parameter_declaration_list.children:
- parameter_name, parameter_type = (
- parameter_declaration.children[1].get_name_and_type(
- parameter_declaration.children[0].get_base_type()
- )
- )
- parameter_type = t_def.array_decay(parameter_type)
- print('type analysis: parameter:', parameter_name)
-
+ for i in range(len(parameter_declaration_list.children)):
+ parameter_declaration = parameter_declaration_list.children[i]
parameter_declarator_identifier = t_def.get_declarator_identifier(
parameter_declaration.children[1]
)
assert parameter_declarator_identifier is not None
+ parameter_name = parameter_declarator_identifier.text[0]
+ parameter_type = _type.formal_parameters[i] # enforce sharing
parameter_scope_identifier = (
parameter_declarator_identifier.scope_identifier
# copy scope_identifier from the DeclaratorIdentifier to the
# ParameterDeclaration, we don't need the declarator anymore
parameter_declaration.scope_identifier = parameter_scope_identifier
+ parameter_declarator_identifier.scope_identifier = None # TEMPORARY
+ parameter_declaration.name = parameter_name # TEMPORARY
+ parameter_declaration.type = parameter_type # TEMPORARY
elif isinstance(declarator_function, t_def.DeclaratorFunctionKAndR):
# has no information about formal parameter types, ignore for now
pass
# copy scope_identifier from the DeclaratorIdentifier to the
# FunctionDefinition, we don't need the declarator anymore
self.scope_identifier = scope_identifier
+ declarator_identifier.scope_identifier = None # TEMPORARY
@t_def.method(t_def.InitDeclarator)
def mid_type_analysis(self, context):
# we use the base type and storage class from the context
else:
assert scope_identifier.type == _type
+ # see if inside a function, for automatic auto storage class
+ _storage_class = context.storage_class
+ if (
+ context.scope.enclosing_scope is not None and
+ _storage_class == t_def.STORAGE_CLASS_NONE
+ ):
+ _storage_class = t_def.STORAGE_CLASS_AUTO
+
if scope_identifier.storage_class == t_def.STORAGE_CLASS_NONE:
- scope_identifier.storage_class = context.storage_class
- elif context.storage_class != t_def.STORAGE_CLASS_NONE:
- assert scope_identifier.storage_class == context.storage_class
+ scope_identifier.storage_class = _storage_class
+ elif _storage_class != t_def.STORAGE_CLASS_NONE:
+ assert scope_identifier.storage_class == _storage_class
# copy scope_identifier from the DeclaratorIdentifier to the
# InitDeclarator, we don't need the declarator anymore
self.scope_identifier = scope_identifier
-
- # see whether this InitDeclarator can have an initializer
- if (
- isinstance(scope_identifier.type, t_def.TypeFunction) or
- scope_identifier.storage_class == t_def.STORAGE_CLASS_EXTERN or
- scope_identifier.storage_class == t_def.STORAGE_CLASS_TYPEDEF
- ):
- assert len(self.children) < 2 # can't have initializer
- elif (
- not isinstance(scope_identifier.type, t_def.TypeArray) or
- len(self.children) < 2
- ):
- assert scope_identifier.type.size >= 0 # must be of determinate size
+ declarator_identifier.scope_identifier = None # TEMPORARY
# push entry on initializer stack to use while visiting initializer,
# popped by the later call to InitDeclarator.type_analysis()
@t_def.method(t_def.DesignatorInitializer)
def mid_type_analysis(self, context):
_type, index, max_index = context.initializer_stack[-1]
+ self.type = _type # the starting point for applying the indices
if len(self.children[0].children):
# with designator, the designator says which element to fill
# note: this resets index position, but only for the first designator
# get numeric index from designator
expression = designator.children[0]
- assert expression.type == base_type.type_ssize_t
+ assert expression.type == t_def.type_ssize_t
assert isinstance(expression.value, t_def.ValueInt)
i = expression.value.value
)
size += member_type.size
align = max(align, member_type.align)
+
+ # make the size a multiple of the alignment
+ align_m1 = align - 1
+ size = (size + align_m1) & ~align_m1
+
_type.size = size
_type.align = align
_type.members = members
# copy scope_tag from the TagIdentifier to the
# StructSpecifier, we don't need the identifier anymore
self.scope_tag = scope_tag
+ self.children[0].scope_tag = None # TEMPORARY
@t_def.method(t_def.UnionSpecifier)
def type_analysis(self, context):
# create a TypeUnion placeholder with no members initially
)
size = max(size, member_type.size)
align = max(align, member_type.align)
+
+ # make the size a multiple of the alignment
+ align_m1 = align - 1
+ size = (size + align_m1) & ~align_m1
+
_type.size = size
_type.align = align
_type.members = members
# copy scope_tag from the TagIdentifier to the
# UnionSpecifier, we don't need the identifier anymore
self.scope_tag = scope_tag
+ self.children[0].scope_tag = None # TEMPORARY
@t_def.method(t_def.EnumSpecifier)
def type_analysis(self, context):
# create a TypeEnum placeholder with no members initially
member_name = identifier.text[0]
assert member_name not in members
- #if len(enumerator.children) >= 2:
- # expression = enumerator.children[1]
- # assert expression.type == base_type.type_signed_int
- # assert isinstance(expression.value, t_def.ValueInt)
- # value = expression.value.value
+ if len(enumerator.children) >= 2:
+ expression = enumerator.children[1]
+ assert expression.type == t_def.type_signed_int
+ assert isinstance(expression.value, t_def.ValueInt)
+ value = expression.value.value
members[member_name] = t_def.TypeEnum.Member(
name = member_name,
identifier.scope_identifier.storage_class = (
t_def.STORAGE_CLASS_ENUM_MEMBER
)
+ identifier.scope_identifier = None # TEMPORARY
value += 1
_type.members = members
# copy scope_tag from the TagIdentifier to the
# EnumSpecifier, we don't need the identifier anymore
self.scope_tag = scope_tag
+ self.children[0].scope_tag = None # TEMPORARY
@t_def.method(t_def.InitDeclarator)
def type_analysis(self, context):
# pop entry from initializer stack used while visiting initializer,
_, _, max_index = context.initializer_stack.pop()
assert len(context.initializer_stack) == 0
+ # see if it is being defined here
_type = self.scope_identifier.type
_storage_class = self.scope_identifier.storage_class
if (
_storage_class == t_def.STORAGE_CLASS_EXTERN or
_storage_class == t_def.STORAGE_CLASS_TYPEDEF
):
- assert len(self.children) < 2 # can't have initializer
- elif (
- isinstance(_type, t_def.TypeArray) and
- _type.element_count == -1 and
- len(self.children) >= 2
- ):
- # size of indeterminate sized array can be deduced from initializer
- element_size = _type.element_type.size
- assert element_size >= 0 # must be of determinate size
- _type.size = max_index * element_size
- _type.element_count = max_index
+ # no, can't have initializer
+ assert len(self.children) < 2
else:
+ # yes, can have initializer, allocate space
+ if (
+ isinstance(_type, t_def.TypeArray) and
+ _type.element_count == -1 and
+ len(self.children) >= 2
+ ):
+ # size of indeterminate sized array can be deduced from initializer
+ element_size = _type.element_type.size
+ assert element_size >= 0 # must be of determinate size
+ _type.size = max_index * element_size
+ _type.element_count = max_index
+
assert _type.size >= 0 # must be of determinate size
+ align_m1 = _type.align - 1
+ context.scope.size = (context.scope.size + align_m1) & ~align_m1
+ self.scope_identifier.offset = context.scope.size
+ context.scope.size += _type.size
+@t_def.method(t_def.TypeName)
+def type_analysis(self, context):
+ name, self.type = self.children[1].get_name_and_type(
+ self.children[0].get_base_type()
+ )
+ assert len(name) == 0
@t_def.method(t_def.Expression)
def type_analysis(self, context):
self.calc_type()
# process typed parameters
for i in range(n_formal_parameters):
- actual_parameters.children[i] = add_cast(
+ actual_parameters.children[i] = t_def.add_cast(
function_type.formal_parameters[i],
actual_parameters.children[i]
)
for i in range(n_formal_parameters, len(actual_parameters.children)):
rank = actual_parameters.children[i].type.rank
if rank >= 0 and rank < t_def.INT_RANK:
- actual_parameters.children[i] = add_cast(
- base_type.type_signed_int,
+ actual_parameters.children[i] = t_def.add_cast(
+ t_def.type_signed_int,
actual_parameters.children[i]
)
elif rank >= t_def.FLOAT_RANK and rank < t_def.DOUBLE_RANK:
- actual_parameters.children[i] = add_cast(
+ actual_parameters.children[i] = t_def.add_cast(
rank_to_type[rank + t_def.DOUBLE_RANK - t_def.FLOAT_RANK],
actual_parameters.children[i]
)
self.type = context.initializer_stack[-1][0]
@t_def.method(t_def.InitializerExpression)
def type_analysis(self, context):
- self.children[0] = add_cast(
+ self.children[0] = t_def.add_cast(
context.initializer_stack[-1][0],
self.children[0]
)
not isinstance(self.children[2], t_def.ExpressionEmpty) and
not isinstance(self.children[2], t_def.ExpressionAsterisk)
):
- self.children[2] = add_cast(
- base_type.type_size_t,
+ self.children[2] = t_def.add_cast(
+ t_def.type_size_t,
self.children[2]
)
@t_def.method(t_def.Enumerator)
def type_analysis(self, context):
if len(self.children) >= 2:
- self.children[1] = add_cast(
- base_type.type_signed_int,
+ self.children[1] = t_def.add_cast(
+ t_def.type_signed_int,
self.children[1]
)
@t_def.method(t_def.StructDeclarator)
def type_analysis(self, context):
- self.children[1] = add_cast(
- base_type.type_signed_int,
+ self.children[1] = t_def.add_cast(
+ t_def.type_signed_int,
self.children[1],
)
@t_def.method(t_def.AlignAsExpression)
def type_analysis(self, context):
- self.children[0] = add_cast(
- base_type.type_size_t,
+ self.children[0] = t_def.add_cast(
+ t_def.type_size_t,
self.children[0],
)
@t_def.method(t_def.DesignatorIndex)
def type_analysis(self, context):
- self.children[0] = add_cast(
- base_type.type_ssize_t,
+ self.children[0] = t_def.add_cast(
+ t_def.type_ssize_t,
self.children[0],
)
@t_def.method(t_def.StaticAssertDeclaration)
def type_analysis(self, context):
- self.children[0] = add_cast(
- base_type.type_bool,
+ self.children[0] = t_def.add_cast(
+ t_def.type_bool,
self.children[0],
)
@t_def.method(t_def.StatementCase)
def type_analysis(self, context):
- self.children[0] = add_cast(
+ self.children[0] = t_def.add_cast(
context.case_type,
self.children[0],
)
@t_def.method(t_def.StatementExpression)
def type_analysis(self, context):
- self.children[0] = add_cast(
- base_type.type_void,
+ self.children[0] = t_def.add_cast(
+ t_def.type_void,
self.children[0],
)
@t_def.method(t_def.StatementIf)
def type_analysis(self, context):
- self.children[0] = add_cast(
- base_type.type_bool,
+ self.children[0] = t_def.add_cast(
+ t_def.type_bool,
self.children[0],
)
@t_def.method(t_def.StatementWhile)
def type_analysis(self, context):
- self.children[0] = add_cast(
- base_type.type_bool,
+ self.children[0] = t_def.add_cast(
+ t_def.type_bool,
self.children[0],
)
@t_def.method(t_def.StatementDoWhile)
def type_analysis(self, context):
- self.children[1] = add_cast(
- base_type.type_bool,
+ self.children[1] = t_def.add_cast(
+ t_def.type_bool,
self.children[1],
)
@t_def.method(t_def.StatementFor)
def type_analysis(self, context):
if not isinstance(self.children[1], t_def.ExpressionEmpty):
- self.children[1] = add_cast(
- base_type.type_bool,
+ self.children[1] = t_def.add_cast(
+ t_def.type_bool,
self.children[1],
)
if not isinstance(self.children[2], t_def.ExpressionEmpty):
- self.children[2] = add_cast(
- base_type.type_void,
+ self.children[2] = t_def.add_cast(
+ t_def.type_void,
self.children[2],
)
@t_def.method(t_def.StatementReturn)
def type_analysis(self, context):
- self.children[0] = add_cast(
+ self.children[0] = t_def.add_cast(
context.return_type,
self.children[0],
)