1f051f5d1SMatt Morehouse //==-- proto_to_cxx.cpp - Protobuf-C++ conversion --------------------------==//
2f051f5d1SMatt Morehouse //
3*2946cd70SChandler Carruth // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4*2946cd70SChandler Carruth // See https://llvm.org/LICENSE.txt for license information.
5*2946cd70SChandler Carruth // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6f051f5d1SMatt Morehouse //
7f051f5d1SMatt Morehouse //===----------------------------------------------------------------------===//
8f051f5d1SMatt Morehouse //
9f051f5d1SMatt Morehouse // Implements functions for converting between protobufs and C++.
10f051f5d1SMatt Morehouse //
11f051f5d1SMatt Morehouse //===----------------------------------------------------------------------===//
12f051f5d1SMatt Morehouse
13f051f5d1SMatt Morehouse #include "proto_to_cxx.h"
14f051f5d1SMatt Morehouse #include "cxx_proto.pb.h"
15f051f5d1SMatt Morehouse
16f051f5d1SMatt Morehouse #include <ostream>
17f051f5d1SMatt Morehouse #include <sstream>
18f051f5d1SMatt Morehouse
19f051f5d1SMatt Morehouse namespace clang_fuzzer {
20f051f5d1SMatt Morehouse
21f051f5d1SMatt Morehouse // Forward decls.
22f051f5d1SMatt Morehouse std::ostream &operator<<(std::ostream &os, const BinaryOp &x);
23f051f5d1SMatt Morehouse std::ostream &operator<<(std::ostream &os, const StatementSeq &x);
24f051f5d1SMatt Morehouse
25f051f5d1SMatt Morehouse // Proto to C++.
operator <<(std::ostream & os,const Const & x)26f051f5d1SMatt Morehouse std::ostream &operator<<(std::ostream &os, const Const &x) {
27f051f5d1SMatt Morehouse return os << "(" << x.val() << ")";
28f051f5d1SMatt Morehouse }
operator <<(std::ostream & os,const VarRef & x)29f051f5d1SMatt Morehouse std::ostream &operator<<(std::ostream &os, const VarRef &x) {
30f051f5d1SMatt Morehouse return os << "a[" << (static_cast<uint32_t>(x.varnum()) % 100) << "]";
31f051f5d1SMatt Morehouse }
operator <<(std::ostream & os,const Lvalue & x)32f051f5d1SMatt Morehouse std::ostream &operator<<(std::ostream &os, const Lvalue &x) {
33f051f5d1SMatt Morehouse return os << x.varref();
34f051f5d1SMatt Morehouse }
operator <<(std::ostream & os,const Rvalue & x)35f051f5d1SMatt Morehouse std::ostream &operator<<(std::ostream &os, const Rvalue &x) {
36f051f5d1SMatt Morehouse if (x.has_varref()) return os << x.varref();
37f051f5d1SMatt Morehouse if (x.has_cons()) return os << x.cons();
38f051f5d1SMatt Morehouse if (x.has_binop()) return os << x.binop();
39f051f5d1SMatt Morehouse return os << "1";
40f051f5d1SMatt Morehouse }
operator <<(std::ostream & os,const BinaryOp & x)41f051f5d1SMatt Morehouse std::ostream &operator<<(std::ostream &os, const BinaryOp &x) {
42f051f5d1SMatt Morehouse os << "(" << x.left();
43f051f5d1SMatt Morehouse switch (x.op()) {
44f051f5d1SMatt Morehouse case BinaryOp::PLUS: os << "+"; break;
45f051f5d1SMatt Morehouse case BinaryOp::MINUS: os << "-"; break;
46f051f5d1SMatt Morehouse case BinaryOp::MUL: os << "*"; break;
47f051f5d1SMatt Morehouse case BinaryOp::DIV: os << "/"; break;
48f051f5d1SMatt Morehouse case BinaryOp::MOD: os << "%"; break;
49f051f5d1SMatt Morehouse case BinaryOp::XOR: os << "^"; break;
50f051f5d1SMatt Morehouse case BinaryOp::AND: os << "&"; break;
51f051f5d1SMatt Morehouse case BinaryOp::OR: os << "|"; break;
52f051f5d1SMatt Morehouse case BinaryOp::EQ: os << "=="; break;
53f051f5d1SMatt Morehouse case BinaryOp::NE: os << "!="; break;
54f051f5d1SMatt Morehouse case BinaryOp::LE: os << "<="; break;
55f051f5d1SMatt Morehouse case BinaryOp::GE: os << ">="; break;
56f051f5d1SMatt Morehouse case BinaryOp::LT: os << "<"; break;
57f051f5d1SMatt Morehouse case BinaryOp::GT: os << ">"; break;
58f051f5d1SMatt Morehouse }
59f051f5d1SMatt Morehouse return os << x.right() << ")";
60f051f5d1SMatt Morehouse }
operator <<(std::ostream & os,const AssignmentStatement & x)61f051f5d1SMatt Morehouse std::ostream &operator<<(std::ostream &os, const AssignmentStatement &x) {
62f051f5d1SMatt Morehouse return os << x.lvalue() << "=" << x.rvalue() << ";\n";
63f051f5d1SMatt Morehouse }
operator <<(std::ostream & os,const IfElse & x)64f051f5d1SMatt Morehouse std::ostream &operator<<(std::ostream &os, const IfElse &x) {
65f051f5d1SMatt Morehouse return os << "if (" << x.cond() << "){\n"
66f051f5d1SMatt Morehouse << x.if_body() << "} else { \n"
67f051f5d1SMatt Morehouse << x.else_body() << "}\n";
68f051f5d1SMatt Morehouse }
operator <<(std::ostream & os,const While & x)69f051f5d1SMatt Morehouse std::ostream &operator<<(std::ostream &os, const While &x) {
70f051f5d1SMatt Morehouse return os << "while (" << x.cond() << "){\n" << x.body() << "}\n";
71f051f5d1SMatt Morehouse }
operator <<(std::ostream & os,const Statement & x)72f051f5d1SMatt Morehouse std::ostream &operator<<(std::ostream &os, const Statement &x) {
73f051f5d1SMatt Morehouse if (x.has_assignment()) return os << x.assignment();
74f051f5d1SMatt Morehouse if (x.has_ifelse()) return os << x.ifelse();
75f051f5d1SMatt Morehouse if (x.has_while_loop()) return os << x.while_loop();
76f051f5d1SMatt Morehouse return os << "(void)0;\n";
77f051f5d1SMatt Morehouse }
operator <<(std::ostream & os,const StatementSeq & x)78f051f5d1SMatt Morehouse std::ostream &operator<<(std::ostream &os, const StatementSeq &x) {
79f051f5d1SMatt Morehouse for (auto &st : x.statements()) os << st;
80f051f5d1SMatt Morehouse return os;
81f051f5d1SMatt Morehouse }
operator <<(std::ostream & os,const Function & x)82f051f5d1SMatt Morehouse std::ostream &operator<<(std::ostream &os, const Function &x) {
83f051f5d1SMatt Morehouse return os << "void foo(int *a) {\n" << x.statements() << "}\n";
84f051f5d1SMatt Morehouse }
85f051f5d1SMatt Morehouse
86f051f5d1SMatt Morehouse // ---------------------------------
87f051f5d1SMatt Morehouse
FunctionToString(const Function & input)88f051f5d1SMatt Morehouse std::string FunctionToString(const Function &input) {
89f051f5d1SMatt Morehouse std::ostringstream os;
90f051f5d1SMatt Morehouse os << input;
91f051f5d1SMatt Morehouse return os.str();
92f051f5d1SMatt Morehouse
93f051f5d1SMatt Morehouse }
ProtoToCxx(const uint8_t * data,size_t size)94f051f5d1SMatt Morehouse std::string ProtoToCxx(const uint8_t *data, size_t size) {
95f051f5d1SMatt Morehouse Function message;
96d08e0a78SMatt Morehouse if (!message.ParsePartialFromArray(data, size))
97f051f5d1SMatt Morehouse return "#error invalid proto\n";
98f051f5d1SMatt Morehouse return FunctionToString(message);
99f051f5d1SMatt Morehouse }
100f051f5d1SMatt Morehouse
101f051f5d1SMatt Morehouse } // namespace clang_fuzzer
102