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 13namespace v8 { 14namespace internal { 15namespace torque { 16namespace cpp { 17 18struct TemplateParameter { 19 explicit TemplateParameter(std::string name) : name(std::move(name)) {} 20 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 27class Class { 28 public: 29 explicit Class(std::string name) : name_(std::move(name)) {} 30 Class(std::vector<TemplateParameter> template_parameters, std::string name) 31 : template_parameters_(std::move(template_parameters)), 32 name_(std::move(name)) {} 33 34 std::string GetName() const { return name_; } 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 53class 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 = {}) 68 : type(std::move(type)), 69 name(std::move(name)), 70 default_value(std::move(default_value)) {} 71 }; 72 73 explicit Function(std::string name) 74 : pos_(CurrentSourcePosition::Get()), 75 owning_class_(nullptr), 76 name_(std::move(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 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 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 } 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); } 120 FUNCTION_FLAG_LIST(ACCESSOR) 121#undef ACCESSOR 122 123 void SetDescription(std::string description) { 124 description_ = std::move(description); 125 } 126 void SetName(std::string name) { name_ = std::move(name); } 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 } 143 std::vector<Parameter> GetParameters() const { return parameters_; } 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 177DEFINE_OPERATORS_FOR_FLAGS(base::Flags<Function::FunctionFlag>) 178#undef FUNCTION_FLAG_LIST 179 180class 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 208class IncludeGuardScope { 209 public: 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; 215 IncludeGuardScope(IncludeGuardScope&& other) V8_NOEXCEPT : file_(nullptr), 216 name_() { 217 std::swap(file_, other.file_); 218 std::swap(name_, other.name_); 219 } 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