1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | |
8 | |
9 | |
10 | |
11 | |
12 | |
13 | |
14 | |
15 | |
16 | |
17 | |
18 | |
19 | #include "cxx_loop_proto.pb.h" |
20 | #include "proto_to_cxx.h" |
21 | |
22 | |
23 | #include <google/protobuf/text_format.h> |
24 | |
25 | #include <ostream> |
26 | #include <sstream> |
27 | |
28 | namespace clang_fuzzer { |
29 | |
30 | static bool inner_loop = false; |
31 | class InnerLoop { |
32 | public: |
33 | InnerLoop() { |
34 | inner_loop = true; |
35 | } |
36 | ~InnerLoop() { |
37 | inner_loop = false; |
38 | } |
39 | }; |
40 | |
41 | |
42 | std::ostream &operator<<(std::ostream &os, const BinaryOp &x); |
43 | std::ostream &operator<<(std::ostream &os, const StatementSeq &x); |
44 | |
45 | |
46 | std::ostream &operator<<(std::ostream &os, const Const &x) { |
47 | return os << "(" << x.val() << ")"; |
48 | } |
49 | std::ostream &operator<<(std::ostream &os, const VarRef &x) { |
50 | std::string which_loop = inner_loop ? "j" : "i"; |
51 | switch (x.arr()) { |
52 | case VarRef::ARR_A: |
53 | return os << "a[" << which_loop << "]"; |
54 | case VarRef::ARR_B: |
55 | return os << "b[" << which_loop << "]"; |
56 | case VarRef::ARR_C: |
57 | return os << "c[" << which_loop << "]"; |
58 | } |
59 | } |
60 | std::ostream &operator<<(std::ostream &os, const Rvalue &x) { |
61 | if (x.has_cons()) |
62 | return os << x.cons(); |
63 | if (x.has_binop()) |
64 | return os << x.binop(); |
65 | if (x.has_varref()) |
66 | return os << x.varref(); |
67 | return os << "1"; |
68 | } |
69 | std::ostream &operator<<(std::ostream &os, const BinaryOp &x) { |
70 | os << "(" << x.left(); |
71 | switch (x.op()) { |
72 | case BinaryOp::PLUS: |
73 | os << "+"; |
74 | break; |
75 | case BinaryOp::MINUS: |
76 | os << "-"; |
77 | break; |
78 | case BinaryOp::MUL: |
79 | os << "*"; |
80 | break; |
81 | case BinaryOp::XOR: |
82 | os << "^"; |
83 | break; |
84 | case BinaryOp::AND: |
85 | os << "&"; |
86 | break; |
87 | case BinaryOp::OR: |
88 | os << "|"; |
89 | break; |
90 | case BinaryOp::EQ: |
91 | os << "=="; |
92 | break; |
93 | case BinaryOp::NE: |
94 | os << "!="; |
95 | break; |
96 | case BinaryOp::LE: |
97 | os << "<="; |
98 | break; |
99 | case BinaryOp::GE: |
100 | os << ">="; |
101 | break; |
102 | case BinaryOp::LT: |
103 | os << "<"; |
104 | break; |
105 | case BinaryOp::GT: |
106 | os << ">"; |
107 | break; |
108 | } |
109 | return os << x.right() << ")"; |
110 | } |
111 | std::ostream &operator<<(std::ostream &os, const AssignmentStatement &x) { |
112 | return os << x.varref() << "=" << x.rvalue() << ";\n"; |
113 | } |
114 | std::ostream &operator<<(std::ostream &os, const Statement &x) { |
115 | return os << x.assignment(); |
116 | } |
117 | std::ostream &operator<<(std::ostream &os, const StatementSeq &x) { |
118 | for (auto &st : x.statements()) |
119 | os << st; |
120 | return os; |
121 | } |
122 | void NestedLoopToString(std::ostream &os, const LoopFunction &x) { |
123 | os << "void foo(int *a, int *b, int *__restrict__ c, size_t s) {\n" |
124 | << "for (int i=0; i<s; i++){\n" |
125 | << "for (int j=0; j<s; j++){\n"; |
126 | { |
127 | InnerLoop IL; |
128 | os << x.inner_statements() << "}\n"; |
129 | } |
130 | os << x.outer_statements() << "}\n}\n"; |
131 | } |
132 | void SingleLoopToString(std::ostream &os, const LoopFunction &x) { |
133 | os << "void foo(int *a, int *b, int *__restrict__ c, size_t s) {\n" |
134 | << "for (int i=0; i<s; i++){\n" |
135 | << x.outer_statements() << "}\n}\n"; |
136 | } |
137 | std::ostream &operator<<(std::ostream &os, const LoopFunction &x) { |
138 | if (x.has_inner_statements()) |
139 | NestedLoopToString(os, x); |
140 | else |
141 | SingleLoopToString(os, x); |
142 | return os; |
143 | } |
144 | |
145 | |
146 | |
147 | std::string LoopFunctionToString(const LoopFunction &input) { |
148 | std::ostringstream os; |
149 | os << input; |
150 | return os.str(); |
151 | } |
152 | std::string LoopProtoToCxx(const uint8_t *data, size_t size) { |
153 | LoopFunction message; |
154 | if (!message.ParsePartialFromArray(data, size)) |
155 | return "#error invalid proto\n"; |
156 | return LoopFunctionToString(message); |
157 | } |
158 | |
159 | } |
160 | |