Project

General

Profile

root / trunk / compiler / cppAst / ast / types / IntType.hpp @ 7

1
/**
2
  *
3
  *                  OOAS Compiler - C++ AST
4
  *
5
  * Copyright 2015, AIT Austrian Institute of Technology.
6
  * All rights reserved.
7
  *
8
  * SEE THE "LICENSE" FILE FOR THE TERMS UNDER WHICH THIS FILE IS PROVIDED.
9
  *
10
  * If you modify the file please update the list of contributors below to in-
11
  * clude your name. Please also stick to the coding convention of using TABs
12
  * to do the basic (block-level) indentation and spaces for anything after
13
  * that. (Enable the display of special chars and it should be pretty obvious
14
  * what this means.) Also, remove all trailing whitespace.
15
  *
16
  * Contributors:
17
  *               Willibald Krenn (AIT)
18
  *               Stephan Zimmerer (AIT)
19
  *               Christoph Czurda (AIT)
20
  *
21
  */
22

    
23

    
24

    
25

    
26
#pragma once
27

    
28
#include <cstdint>
29
#include <ast/types/Type.hpp>
30
#include <ast/IAstVisitor.hpp>
31
#include <boost/format.hpp>
32
#include <iostream>
33

    
34
namespace Ast {
35

    
36
class IntType
37
        : public Type
38
{
39
protected:
40
        std::int64_t m_low;
41
        std::int64_t m_high;
42

    
43
        IntType(): Type(TypeKind::IntType), m_low (0), m_high(0) {}
44

    
45
        IntType(const IntType& toCopy):
46
                Type(toCopy),
47
                m_low (toCopy.m_low),
48
                m_high(toCopy.m_high)
49
        {}
50
        static IntType* create() {return new IntType();}
51
        static IntType* createCopy(const IntType& toCopy) {return new IntType(toCopy);}
52
public:
53
        friend class Ast;
54
        friend class Type;
55

    
56
        void init(TypeIdentifier* id, bool anonymousType, std::int64_t low, std::int64_t high)
57
        {
58
                Type::init(id,anonymousType);
59
                m_low = low;
60
                m_high = high;
61
        }
62

    
63
        int64_t rangeLow() const {return m_low;};
64
        int64_t rangeHigh() const {return m_high;};
65

    
66
        void accept(IAstVisitor& visitor) override {visitor.visit(this);};
67

    
68
        static bool firstTypeLessRange(IntType* first, IntType* second) {
69
                return first->m_low > second->m_low || first->m_high < second->m_high;
70
        }
71

    
72
        bool isSigned() override {return m_low < 0;}
73

    
74
        uint32_t bitwidth() override {
75
                if (m_low == INT64_MIN || m_high == INT64_MAX)
76
                        return 64;
77

    
78
                std::uint32_t result = 0;
79
                if (m_low < 0 && m_high > 0) {
80
                        std::uint32_t bitsforlow = (std::uint32_t) std::floor(std::log2(std::abs(m_low))) + 1;
81
                        std::uint32_t bitsforhigh = (std::uint32_t) std::floor(std::log2(std::abs(m_high))) + 1;
82
                        if (bitsforlow <= bitsforhigh)
83
                                result = bitsforhigh + 1; // we need one additional bit to represent the negative numbers
84
                        else
85
                                result = bitsforlow;      // positive values are included
86
                } else {
87
                        std::uint64_t maxAbs = (std::uint64_t) std::max(std::abs(m_low), std::abs(m_high));
88
                        result = (std::uint32_t) std::floor(std::log2(maxAbs)) + 1;
89
                }
90

    
91
                // check the result!
92
                if (isSigned()) {
93
                        std::int64_t maxVal = (std::int64_t)(((std::uint64_t)1 << result) - 1);
94
                        std::int64_t minVal = (std::int64_t)(((std::uint64_t)-1 << result));
95
                        if (maxVal < m_high) {
96
                                std::cout << " Error converting type (max wrong): "
97
                                                << " low: " << m_low
98
                                                << " high: " << m_high
99
                                                << " bits: " << result
100
                                                << std::endl;
101
                                abort();
102
                        }
103
                        if (minVal > m_low) {
104
                                std::cout << " Error converting type (min wrong): "
105
                                                << " low: " << m_low
106
                                                << " high: " << m_high
107
                                                << " bits: " << result
108
                                                << std::endl;
109
                                abort();
110
                        }
111
                } else {
112
                        std::uint64_t maxVal = (((std::uint64_t)1 << result)-1);
113
                        if (maxVal < (std::uint64_t)m_high) {
114
                                std::cout << " Error converting unsigned type (max wrong): "
115
                                                << " low: " << m_low
116
                                                << " high: " << m_high
117
                                                << " bits: " << result
118
                                                << std::endl;
119
                                abort();
120
                        }
121
                }
122
//                std::cout << " Mapping int type " << toString() << ": "
123
//                                << " low: " << m_low
124
//                                << " high: " << m_high
125
//                                << " bits: " << result
126
//                                << std::endl;
127

    
128
                return result;
129
        }
130
};
131
}