forked from openenclave/oeedger8r-cpp
-
Notifications
You must be signed in to change notification settings - Fork 0
/
args_h_emitter.h
120 lines (107 loc) · 3.08 KB
/
args_h_emitter.h
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
// Copyright (c) Open Enclave SDK contributors.
// Licensed under the MIT License.
#ifndef ARGS_H_EMITTER_H
#define ARGS_H_EMITTER_H
#include <fstream>
#include "ast.h"
#include "utils.h"
class ArgsHEmitter
{
Edl* edl_;
std::ofstream file_;
public:
typedef ArgsHEmitter& R;
template <typename T>
R operator<<(const T& t)
{
file_ << t << "\n";
return out();
}
R out()
{
return *this;
}
public:
ArgsHEmitter(Edl* edl) : edl_(edl), file_()
{
}
void emit(const std::string& dir_with_sep = "")
{
std::string path = dir_with_sep + edl_->name_ + "_args.h";
file_.open(path.c_str(), std::ios::out | std::ios::binary);
std::string guard = "EDGER8R_" + upper(edl_->name_) + "_ARGS_H";
header(out(), guard);
out() << ""
<< "#include <openenclave/bits/result.h>"
<< ""
<< "/**** User includes. ****/";
user_includes();
out() << "/**** User defined types in EDL. ****/";
user_types();
footer(out(), guard);
file_.close();
}
void user_includes()
{
if (edl_->includes_.empty())
out() << "/* There were no user includes. */";
else
for (std::string& inc : edl_->includes_)
out() << "#include " + inc;
out() << "";
}
void user_types()
{
if (edl_->types_.empty())
out() << "/* There were no user defined types. */"
<< "";
else
for (UserType* t : edl_->types_)
{
if (t->tag_ == Enum)
enum_type(t);
else
struct_or_union_type(t);
}
}
void enum_type(UserType* t)
{
std::string uname = upper(t->name_);
// clang-format off
out() << "#ifndef EDGER8R_ENUM_" + uname
<< "#define EDGER8R_ENUM_" + uname
<< "typedef enum " + t->name_
<< "{";
// clang-format on
size_t i = 0;
for (EnumVal& v : t->items_)
{
std::string value =
v.value_ ? (" = " + static_cast<std::string>(*v.value_)) : "";
out() << " " + v.name_ + value +
(i < t->items_.size() - 1 ? "," : "");
++i;
}
out() << "} " + t->name_ + ";"
<< "#endif"
<< "";
}
void struct_or_union_type(UserType* t)
{
std::string tag = t->tag_ == Struct ? "struct" : "union";
std::string utag = upper(tag);
std::string uname = upper(t->name_);
// clang-format off
out() << "#ifndef EDGER8R_" + utag + "_" + uname
<< "#define EDGER8R_" + utag + "_" + uname
<< "typedef " + tag + " " + t->name_
<< "{";
// clang-format on
for (Decl* f : t->fields_)
out() << " " + decl_str(f->name_, f->type_, f->dims_) + ";";
out() << "} " + t->name_ + ";"
<< "#endif"
<< "";
}
};
#endif // ARGS_H_EMITTER