1 //==-- loop_proto_to_cxx.cpp - Protobuf-C++ conversion ---------------------==//
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
7 //===----------------------------------------------------------------------===//
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>
28 namespace clang_fuzzer
{
30 static bool inner_loop
= false;
42 std::ostream
&operator<<(std::ostream
&os
, const BinaryOp
&x
);
43 std::ostream
&operator<<(std::ostream
&os
, const StatementSeq
&x
);
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";
53 return os
<< "a[" << which_loop
<< "]";
55 return os
<< "b[" << which_loop
<< "]";
57 return os
<< "c[" << which_loop
<< "]";
60 std::ostream
&operator<<(std::ostream
&os
, const Rvalue
&x
) {
62 return os
<< x
.cons();
64 return os
<< x
.binop();
66 return os
<< x
.varref();
69 std::ostream
&operator<<(std::ostream
&os
, const BinaryOp
&x
) {
70 os
<< "(" << x
.left();
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())
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";
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
);
141 SingleLoopToString(os
, x
);
145 // ---------------------------------
147 std::string
LoopFunctionToString(const LoopFunction
&input
) {
148 std::ostringstream os
;
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