summaryrefslogtreecommitdiff
path: root/node/ExprNode.hh
blob: 291186cdc287e2a325e08ab714554b538078de69 (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
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
#ifndef PCC_EXPRNODE_H
#define PCC_EXPRNODE_H

#include <list>

#include "BaseNode.hh"
#include "Type.hh"

namespace pcc {
class ExprNode : public BaseNode {
  public:
    ExprNode(Context* context);
    virtual Value CodeGen() = 0;
    std::shared_ptr<Type> GetType();

  protected:
    std::shared_ptr<Type> type_;
};

class BinaryExprNode : public ExprNode {
  public:
    BinaryExprNode(Context* context, BinaryOperator op,
                   std::shared_ptr<ExprNode> left,
                   std::shared_ptr<ExprNode> right);
    virtual Value CodeGen() override;
    virtual int Travel(Traveler& traveler) override;

  protected:
    BinaryOperator op_;
    std::shared_ptr<ExprNode> left_, right_;
};

class UnaryExprNode : public ExprNode {
  public:
    UnaryExprNode(Context* context, UnaryOperator op,
                  std::shared_ptr<ExprNode> value);
    virtual Value CodeGen() override;
    virtual int Travel(Traveler& traveler) override;

  protected:
    UnaryOperator op_;
    std::shared_ptr<ExprNode> value_;
};

// when accessing lvalues, we need an extra load instruction to actually load
// the value from the pointer, this is like clang's 'LValueToRValue' node below.
// c++: int x=7; int y=x;
//  `-CompoundStmt 0xd28720 <col:9, line:9:1>
//    |-DeclStmt 0xd28638 <line:7:2, col:9>
//    | `-VarDecl 0xd285b0 <col:2, col:8> col:6 used x 'int' cinit
//    |   `-IntegerLiteral 0xd28618 <col:8> 'int' 7
//    `-DeclStmt 0xd28708 <line:8:2, col:9>
//      `-VarDecl 0xd28668 <col:2, col:8> col:6 y 'int' cinit
//        `-ImplicitCastExpr 0xd286f0 <col:8> 'int' <LValueToRValue>
//          `-DeclRefExpr 0xd286d0 <col:8> 'int' lvalue Var 0xd285b0 'x' 'int'
class L2RCastingNode : public ExprNode {
  public:
    L2RCastingNode(Context* context, std::shared_ptr<ExprNode> lvalue);
    virtual Value CodeGen() override;
    virtual int Travel(Traveler& traveler) override;

  protected:
    std::shared_ptr<ExprNode> lvalue_;
};

// access an rvalue pointer, this generates one GEP instruction
class PointerAccessNode : public ExprNode {
  public:
    PointerAccessNode(Context* context, std::shared_ptr<ExprNode> lhs,
                      std::shared_ptr<ExprNode> rhs);
    virtual Value CodeGen() override;
    virtual int Travel(Traveler& traveler) override;

  protected:
    std::shared_ptr<ExprNode> lhs_;
    std::shared_ptr<ExprNode> rhs_;
};

// access an array or lvalue pointer
class ArrayAccessNode : public ExprNode {
  public:
    ArrayAccessNode(Context* context, std::shared_ptr<ExprNode> lhs,
                    std::shared_ptr<ExprNode> rhs);
    virtual Value CodeGen() override;
    virtual int Travel(Traveler& traveler) override;

  protected:
    std::shared_ptr<ExprNode> lhs_;
    std::shared_ptr<ExprNode> rhs_;
};

class DereferenceNode : public ExprNode {
  public:
    DereferenceNode(Context* context, std::shared_ptr<ExprNode> lhs);
    virtual Value CodeGen() override;
    virtual int Travel(Traveler& traveler) override;

  protected:
    std::shared_ptr<ExprNode> lhs_;
};

class MemberAccessNode : public ExprNode {
  public:
    MemberAccessNode(Context* context, std::shared_ptr<ExprNode> lhs,
                     std::string&& rhs);
    virtual Value CodeGen() override;
    virtual int Travel(Traveler& traveler) override;

  protected:
    std::shared_ptr<ExprNode> lhs_;
    std::string rhs_;
};

class IdentifierNode : public ExprNode {
  public:
    IdentifierNode(Context* context, const std::string& name);
    virtual Value CodeGen() override;
    virtual int Travel(Traveler& traveler) override;

  protected:
    std::string name_;
};

class FunctionCallNode : public ExprNode {
  public:
    FunctionCallNode(Context* context, const std::string& name,
                     std::list<std::shared_ptr<ExprNode>>&& args);
    virtual Value CodeGen() override;
    virtual int Travel(Traveler& traveler) override;

  protected:
    std::string name_;
    std::list<std::shared_ptr<ExprNode>> args_;
};

} // namespace pcc

#endif // !PCC_EXPRNODE_H