summaryrefslogtreecommitdiff
path: root/TypeManager.hh
blob: ce54dcbda1a389ab8e0ff078656336d00e8c9b14 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
#ifndef PCC_TYPEMANAGER_H
#define PCC_TYPEMANAGER_H

#include <map>
#include <memory>
#include <utility>
#include <vector>

#include "Type.hh"

namespace pcc {
class ExprNode;

enum class BuiltinType {
    VOID,
    BOOLEAN,
    CHAR,
    INTEGER,
    INT64,
    REAL,
    STRING,
    BUILTIN_NUMBER
};
class TypeManager {

  public:
    TypeManager();
    std::shared_ptr<Type> GetBuiltinType(BuiltinType type);
    std::shared_ptr<Type> GetPointerIndexType();
    std::shared_ptr<Type> GetPointerDifferenceType();
    std::shared_ptr<Type> GetRecordMemberIndexType();

    // if call this function twice with the same ElementType, it will return the
    // same shared_ptr to the Type.
    std::shared_ptr<PointerType>
        GetPointerType(std::shared_ptr<Type> ElementType,
                       const char* CustomName = nullptr);

    // record, array and function types are considered unique, unless use type
    // alias, you can't get the same type as previous call to this function.
    std::shared_ptr<RecordType>
        CreateRecordType(const std::vector<RecordMember>& members);

    std::shared_ptr<ArrayType>
        CreateArrayType(std::shared_ptr<Type> ElementType,
                        std::shared_ptr<ExprNode> start,
                        std::shared_ptr<ExprNode> end);

    std::shared_ptr<FunctionType>
        CreateFunctionType(std::shared_ptr<Type> ReturnType,
                           std::vector<std::shared_ptr<Type>> ArgTypes,
                           bool IsVariadic = false);

    // binary operators may change type
    std::pair<std::shared_ptr<Type>, Value>
        CreateOperation(BinaryOperator op, std::shared_ptr<Type> LeftType,
                        std::shared_ptr<Type> RightType, Value left,
                        Value right, Context* context);

    // unary operators never change type
    Value CreateOperation(UnaryOperator op, std::shared_ptr<Type> type, Value v,
                          Context* context);

    Value CreateCast(std::shared_ptr<Type> DstType,
                     std::shared_ptr<Type> SrcType, Value v, Context* context);

  private:
    std::vector<std::shared_ptr<Type>> builtins_;
    std::map<std::shared_ptr<Type>, std::shared_ptr<PointerType>> PointerTypes_;
    std::vector<std::shared_ptr<FunctionType>> FunctionTypes_;
    std::vector<std::shared_ptr<ArrayType>> ArrayTypes_;
    std::vector<std::shared_ptr<RecordType>> RecordTypes_;

    // if we are porting to some 64-bit machines, we can change these types to
    // 64-bit type, in order to make pointers behave correctly
    std::shared_ptr<Type> PointerDifferenceType_;
    std::shared_ptr<Type> PointerIndexType_;
    std::shared_ptr<Type> RecordMemberIndexType_;
};
} // namespace pcc

#endif // !PCC_TYPEMANAGER_H