• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2021 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #ifndef V8_TORQUE_CPP_BUILDER_H_
6 #define V8_TORQUE_CPP_BUILDER_H_
7 
8 #include <stack>
9 
10 #include "src/torque/ast.h"
11 #include "src/torque/types.h"
12 
13 namespace v8 {
14 namespace internal {
15 namespace torque {
16 namespace cpp {
17 
18 struct TemplateParameter {
TemplateParameterTemplateParameter19   explicit TemplateParameter(std::string name) : name(std::move(name)) {}
TemplateParameterTemplateParameter20   TemplateParameter(std::string type, std::string name)
21       : name(std::move(name)), type(std::move(type)) {}
22 
23   std::string name;
24   std::string type;
25 };
26 
27 class Class {
28  public:
Class(std::string name)29   explicit Class(std::string name) : name_(std::move(name)) {}
Class(std::vector<TemplateParameter> template_parameters,std::string name)30   Class(std::vector<TemplateParameter> template_parameters, std::string name)
31       : template_parameters_(std::move(template_parameters)),
32         name_(std::move(name)) {}
33 
GetName()34   std::string GetName() const { return name_; }
GetTemplateParameters()35   std::vector<TemplateParameter> GetTemplateParameters() const {
36     return template_parameters_;
37   }
38 
39  private:
40   std::vector<TemplateParameter> template_parameters_;
41   std::string name_;
42 };
43 
44 #define FUNCTION_FLAG_LIST(V) \
45   V(Inline, 0x01)             \
46   V(V8Inline, 0x03)           \
47   V(Const, 0x04)              \
48   V(Constexpr, 0x08)          \
49   V(Export, 0x10)             \
50   V(Static, 0x20)             \
51   V(Override, 0x40)
52 
53 class Function {
54  public:
55   enum FunctionFlag {
56 #define ENTRY(name, value) k##name = value,
57     FUNCTION_FLAG_LIST(ENTRY)
58 #undef ENTRY
59   };
60 
61   struct Parameter {
62     std::string type;
63     std::string name;
64     std::string default_value;
65 
66     Parameter(std::string type, std::string name,
67               std::string default_value = {})
typeParameter68         : type(std::move(type)),
69           name(std::move(name)),
70           default_value(std::move(default_value)) {}
71   };
72 
Function(std::string name)73   explicit Function(std::string name)
74       : pos_(CurrentSourcePosition::Get()),
75         owning_class_(nullptr),
76         name_(std::move(name)) {}
Function(Class * owning_class,std::string name)77   Function(Class* owning_class, std::string name)
78       : pos_(CurrentSourcePosition::Get()),
79         owning_class_(owning_class),
80         name_(std::move(name)) {}
81   ~Function() = default;
82 
DefaultGetter(std::string return_type,Class * owner,std::string name)83   static Function DefaultGetter(std::string return_type, Class* owner,
84                                 std::string name) {
85     Function getter(owner, std::move(name));
86     getter.SetReturnType(std::move(return_type));
87     getter.SetInline();
88     getter.SetConst();
89     return getter;
90   }
91 
DefaultSetter(Class * owner,std::string name,std::string parameter_type,std::string parameter_name)92   static Function DefaultSetter(Class* owner, std::string name,
93                                 std::string parameter_type,
94                                 std::string parameter_name) {
95     Function setter(owner, std::move(name));
96     setter.SetReturnType("void");
97     setter.AddParameter(std::move(parameter_type), std::move(parameter_name));
98     setter.SetInline();
99     return setter;
100   }
101 
102   void SetFlag(FunctionFlag flag, bool value = true) {
103     if (value) {
104       flags_ = flags_ | flag;
105     } else {
106       flags_ = flags_.without(flag);
107     }
108   }
109   void SetFlags(base::Flags<FunctionFlag> flags, bool value = true) {
110     if (value) {
111       flags_ |= flags;
112     } else {
113       flags_ &= ~flags;
114     }
115   }
HasFlag(FunctionFlag flag)116   bool HasFlag(FunctionFlag flag) const { return (flags_ & flag) == flag; }
117 #define ACCESSOR(name, value)                            \
118   void Set##name(bool v = true) { SetFlag(k##name, v); } \
119   bool Is##name() const { return HasFlag(k##name); }
FUNCTION_FLAG_LIST(ACCESSOR)120   FUNCTION_FLAG_LIST(ACCESSOR)
121 #undef ACCESSOR
122 
123   void SetDescription(std::string description) {
124     description_ = std::move(description);
125   }
SetName(std::string name)126   void SetName(std::string name) { name_ = std::move(name); }
SetReturnType(std::string return_type)127   void SetReturnType(std::string return_type) {
128     return_type_ = std::move(return_type);
129   }
130   void AddParameter(std::string type, std::string name = {},
131                     std::string default_value = {}) {
132     parameters_.emplace_back(std::move(type), std::move(name),
133                              std::move(default_value));
134   }
135   void InsertParameter(int index, std::string type, std::string name = {},
136                        std::string default_value = {}) {
137     DCHECK_GE(index, 0);
138     DCHECK_LE(index, parameters_.size());
139     parameters_.insert(
140         parameters_.begin() + index,
141         Parameter(std::move(type), std::move(name), std::move(default_value)));
142   }
GetParameters()143   std::vector<Parameter> GetParameters() const { return parameters_; }
GetParameterNames()144   std::vector<std::string> GetParameterNames() const {
145     std::vector<std::string> names;
146     std::transform(parameters_.begin(), parameters_.end(),
147                    std::back_inserter(names),
148                    [](const Parameter& p) { return p.name; });
149     return names;
150   }
151 
152   static constexpr int kAutomaticIndentation = -1;
153   void PrintDeclaration(std::ostream& stream,
154                         int indentation = kAutomaticIndentation) const;
155   void PrintDefinition(std::ostream& stream,
156                        const std::function<void(std::ostream&)>& builder,
157                        int indentation = 0) const;
158   void PrintInlineDefinition(std::ostream& stream,
159                              const std::function<void(std::ostream&)>& builder,
160                              int indentation = 2) const;
161   void PrintBeginDefinition(std::ostream& stream, int indentation = 0) const;
162   void PrintEndDefinition(std::ostream& stream, int indentation = 0) const;
163 
164  protected:
165   void PrintDeclarationHeader(std::ostream& stream, int indentation) const;
166 
167  private:
168   SourcePosition pos_;
169   Class* owning_class_;
170   std::string description_;
171   std::string name_;
172   std::string return_type_;
173   std::vector<Parameter> parameters_;
174   base::Flags<FunctionFlag> flags_;
175 };
176 
DEFINE_OPERATORS_FOR_FLAGS(base::Flags<Function::FunctionFlag>)177 DEFINE_OPERATORS_FOR_FLAGS(base::Flags<Function::FunctionFlag>)
178 #undef FUNCTION_FLAG_LIST
179 
180 class File {
181  public:
182   explicit File(std::ostream& stream) : stream_(&stream) {}
183 
184   void BeginIncludeGuard(const std::string& name);
185   void EndIncludeGuard(const std::string& name);
186   void BeginNamespace(std::string name);
187   void BeginNamespace(std::string name0, std::string name1);
188   void EndNamespace(const std::string& name);
189   void EndNamespace(const std::string& name0, const std::string& name1);
190 
191   void AddInclude(std::string include) { includes_.insert(std::move(include)); }
192 
193   template <typename T>
194   File& operator<<(const T& value) {
195     s() << value;
196     return *this;
197   }
198 
199  protected:
200   std::ostream& s() { return *stream_; }
201 
202  private:
203   std::ostream* stream_;
204   std::set<std::string> includes_;
205   std::stack<std::string> namespaces_;
206 };
207 
208 class IncludeGuardScope {
209  public:
IncludeGuardScope(File * file,std::string name)210   explicit IncludeGuardScope(File* file, std::string name)
211       : file_(file), name_(std::move(name)) {
212     file_->BeginIncludeGuard(name_);
213   }
214   IncludeGuardScope(const IncludeGuardScope&) = delete;
IncludeGuardScope(IncludeGuardScope && other)215   IncludeGuardScope(IncludeGuardScope&& other) V8_NOEXCEPT : file_(nullptr),
216                                                              name_() {
217     std::swap(file_, other.file_);
218     std::swap(name_, other.name_);
219   }
~IncludeGuardScope()220   ~IncludeGuardScope() {
221     if (file_) {
222       file_->EndIncludeGuard(name_);
223     }
224   }
225   IncludeGuardScope& operator=(const IncludeGuardScope&) = delete;
226   IncludeGuardScope& operator=(IncludeGuardScope&& other) V8_NOEXCEPT {
227     if (this != &other) {
228       DCHECK_NULL(file_);
229       DCHECK(name_.empty());
230       std::swap(file_, other.file_);
231       std::swap(name_, other.name_);
232     }
233     return *this;
234   }
235 
236  private:
237   File* file_;
238   std::string name_;
239 };
240 
241 }  // namespace cpp
242 }  // namespace torque
243 }  // namespace internal
244 }  // namespace v8
245 
246 #endif  // V8_TORQUE_CPP_BUILDER_H_
247