Esempio n. 1
0
        public override AstNode Visit(ReinterpretCast node)
        {
            // Get the target type and value.
            Expression target = node.GetTargetType();
            Expression value = node.GetValue();

            // Set the type hint to the target.
            target.SetHints(Expression.TypeHint);

            // Visit them.
            target.Accept(this);
            value.Accept(this);

            // Get the target type.
            IChelaType targetType = target.GetNodeType();
            targetType = ExtractActualType(target, targetType);
            if(targetType.IsPassedByReference())
                targetType = ReferenceType.Create(targetType);

            // Check the source type.
            IChelaType valueType = value.GetNodeType();
            if(valueType.IsReference())
            {
                IChelaType refType = DeReferenceType(valueType);
                if(!refType.IsPassedByReference())
                {
                    // Don't load temporary referenced slots.
                    Variable variable = value.GetNodeValue() as Variable;
                    if(variable == null || !variable.IsTemporalReferencedSlot())
                        valueType = refType;
                }
            }
            node.SetCoercionType(valueType);

            // The target and the source type size must be of the same size.
            bool targetPointer = targetType.IsReference() || targetType.IsPointer() ||
                    targetType == ChelaType.GetSizeType() || targetType == ChelaType.GetPtrDiffType();
            bool sourcePointer = valueType.IsReference() || valueType.IsPointer() ||
                    valueType == ChelaType.GetSizeType() || valueType == ChelaType.GetPtrDiffType();

            // Pointer types must match.
            if(sourcePointer != targetPointer)
                Error(node, "Cannot reinterpret_cast between pointer and non-pointer compatible types.");

            // The type sizes must be the same.
            if(!targetPointer && targetType.GetSize() != valueType.GetSize())
                Error(node, "Cannot perform reinterpret_cast with types of differente sizes:\n{0}->{1}",
                    valueType.GetFullName(), targetType.GetFullName());

            // Set the node type.
            node.SetNodeType(targetType);

            return node;
        }