[docs] Add LICENSE.txt to the root of the mono-repo
[llvm-project.git] / clang / tools / clang-fuzzer / proto-to-cxx / loop_proto_to_cxx.cpp
blob114f5fc40ed786e4b8f2b33843089f6f74578a44
1 //==-- loop_proto_to_cxx.cpp - Protobuf-C++ conversion ---------------------==//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // Implements functions for converting between protobufs and C++. Differs from
10 // proto_to_cxx.cpp by wrapping all the generated C++ code in either a single
11 // for loop or two nested loops. Also outputs a different function signature
12 // that includes a size_t parameter for the loop to use. The C++ code generated
13 // is meant to stress the LLVM loop vectorizer.
15 // Still a work in progress.
17 //===----------------------------------------------------------------------===//
19 #include "cxx_loop_proto.pb.h"
20 #include "proto_to_cxx.h"
22 // The following is needed to convert protos in human-readable form
23 #include <google/protobuf/text_format.h>
25 #include <ostream>
26 #include <sstream>
28 namespace clang_fuzzer {
30 static bool inner_loop = false;
31 class InnerLoop {
32 public:
33 InnerLoop() {
34 inner_loop = true;
36 ~InnerLoop() {
37 inner_loop = false;
41 // Forward decls.
42 std::ostream &operator<<(std::ostream &os, const BinaryOp &x);
43 std::ostream &operator<<(std::ostream &os, const StatementSeq &x);
45 // Proto to C++.
46 std::ostream &operator<<(std::ostream &os, const Const &x) {
47 return os << "(" << x.val() << ")";
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 << "]";
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";
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;
109 return os << x.right() << ")";
111 std::ostream &operator<<(std::ostream &os, const AssignmentStatement &x) {
112 return os << x.varref() << "=" << x.rvalue() << ";\n";
114 std::ostream &operator<<(std::ostream &os, const Statement &x) {
115 return os << x.assignment();
117 std::ostream &operator<<(std::ostream &os, const StatementSeq &x) {
118 for (auto &st : x.statements())
119 os << st;
120 return os;
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";
127 InnerLoop IL;
128 os << x.inner_statements() << "}\n";
130 os << x.outer_statements() << "}\n}\n";
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";
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;
145 // ---------------------------------
147 std::string LoopFunctionToString(const LoopFunction &input) {
148 std::ostringstream os;
149 os << input;
150 return os.str();
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);
159 } // namespace clang_fuzzer