11cb0ef41Sopenharmony_ci// Copyright 2021 the V8 project authors. All rights reserved. 21cb0ef41Sopenharmony_ci// Use of this source code is governed by a BSD-style license that can be 31cb0ef41Sopenharmony_ci// found in the LICENSE file. 41cb0ef41Sopenharmony_ci 51cb0ef41Sopenharmony_ci#ifndef V8_TORQUE_CPP_BUILDER_H_ 61cb0ef41Sopenharmony_ci#define V8_TORQUE_CPP_BUILDER_H_ 71cb0ef41Sopenharmony_ci 81cb0ef41Sopenharmony_ci#include <stack> 91cb0ef41Sopenharmony_ci 101cb0ef41Sopenharmony_ci#include "src/torque/ast.h" 111cb0ef41Sopenharmony_ci#include "src/torque/types.h" 121cb0ef41Sopenharmony_ci 131cb0ef41Sopenharmony_cinamespace v8 { 141cb0ef41Sopenharmony_cinamespace internal { 151cb0ef41Sopenharmony_cinamespace torque { 161cb0ef41Sopenharmony_cinamespace cpp { 171cb0ef41Sopenharmony_ci 181cb0ef41Sopenharmony_cistruct TemplateParameter { 191cb0ef41Sopenharmony_ci explicit TemplateParameter(std::string name) : name(std::move(name)) {} 201cb0ef41Sopenharmony_ci TemplateParameter(std::string type, std::string name) 211cb0ef41Sopenharmony_ci : name(std::move(name)), type(std::move(type)) {} 221cb0ef41Sopenharmony_ci 231cb0ef41Sopenharmony_ci std::string name; 241cb0ef41Sopenharmony_ci std::string type; 251cb0ef41Sopenharmony_ci}; 261cb0ef41Sopenharmony_ci 271cb0ef41Sopenharmony_ciclass Class { 281cb0ef41Sopenharmony_ci public: 291cb0ef41Sopenharmony_ci explicit Class(std::string name) : name_(std::move(name)) {} 301cb0ef41Sopenharmony_ci Class(std::vector<TemplateParameter> template_parameters, std::string name) 311cb0ef41Sopenharmony_ci : template_parameters_(std::move(template_parameters)), 321cb0ef41Sopenharmony_ci name_(std::move(name)) {} 331cb0ef41Sopenharmony_ci 341cb0ef41Sopenharmony_ci std::string GetName() const { return name_; } 351cb0ef41Sopenharmony_ci std::vector<TemplateParameter> GetTemplateParameters() const { 361cb0ef41Sopenharmony_ci return template_parameters_; 371cb0ef41Sopenharmony_ci } 381cb0ef41Sopenharmony_ci 391cb0ef41Sopenharmony_ci private: 401cb0ef41Sopenharmony_ci std::vector<TemplateParameter> template_parameters_; 411cb0ef41Sopenharmony_ci std::string name_; 421cb0ef41Sopenharmony_ci}; 431cb0ef41Sopenharmony_ci 441cb0ef41Sopenharmony_ci#define FUNCTION_FLAG_LIST(V) \ 451cb0ef41Sopenharmony_ci V(Inline, 0x01) \ 461cb0ef41Sopenharmony_ci V(V8Inline, 0x03) \ 471cb0ef41Sopenharmony_ci V(Const, 0x04) \ 481cb0ef41Sopenharmony_ci V(Constexpr, 0x08) \ 491cb0ef41Sopenharmony_ci V(Export, 0x10) \ 501cb0ef41Sopenharmony_ci V(Static, 0x20) \ 511cb0ef41Sopenharmony_ci V(Override, 0x40) 521cb0ef41Sopenharmony_ci 531cb0ef41Sopenharmony_ciclass Function { 541cb0ef41Sopenharmony_ci public: 551cb0ef41Sopenharmony_ci enum FunctionFlag { 561cb0ef41Sopenharmony_ci#define ENTRY(name, value) k##name = value, 571cb0ef41Sopenharmony_ci FUNCTION_FLAG_LIST(ENTRY) 581cb0ef41Sopenharmony_ci#undef ENTRY 591cb0ef41Sopenharmony_ci }; 601cb0ef41Sopenharmony_ci 611cb0ef41Sopenharmony_ci struct Parameter { 621cb0ef41Sopenharmony_ci std::string type; 631cb0ef41Sopenharmony_ci std::string name; 641cb0ef41Sopenharmony_ci std::string default_value; 651cb0ef41Sopenharmony_ci 661cb0ef41Sopenharmony_ci Parameter(std::string type, std::string name, 671cb0ef41Sopenharmony_ci std::string default_value = {}) 681cb0ef41Sopenharmony_ci : type(std::move(type)), 691cb0ef41Sopenharmony_ci name(std::move(name)), 701cb0ef41Sopenharmony_ci default_value(std::move(default_value)) {} 711cb0ef41Sopenharmony_ci }; 721cb0ef41Sopenharmony_ci 731cb0ef41Sopenharmony_ci explicit Function(std::string name) 741cb0ef41Sopenharmony_ci : pos_(CurrentSourcePosition::Get()), 751cb0ef41Sopenharmony_ci owning_class_(nullptr), 761cb0ef41Sopenharmony_ci name_(std::move(name)) {} 771cb0ef41Sopenharmony_ci Function(Class* owning_class, std::string name) 781cb0ef41Sopenharmony_ci : pos_(CurrentSourcePosition::Get()), 791cb0ef41Sopenharmony_ci owning_class_(owning_class), 801cb0ef41Sopenharmony_ci name_(std::move(name)) {} 811cb0ef41Sopenharmony_ci ~Function() = default; 821cb0ef41Sopenharmony_ci 831cb0ef41Sopenharmony_ci static Function DefaultGetter(std::string return_type, Class* owner, 841cb0ef41Sopenharmony_ci std::string name) { 851cb0ef41Sopenharmony_ci Function getter(owner, std::move(name)); 861cb0ef41Sopenharmony_ci getter.SetReturnType(std::move(return_type)); 871cb0ef41Sopenharmony_ci getter.SetInline(); 881cb0ef41Sopenharmony_ci getter.SetConst(); 891cb0ef41Sopenharmony_ci return getter; 901cb0ef41Sopenharmony_ci } 911cb0ef41Sopenharmony_ci 921cb0ef41Sopenharmony_ci static Function DefaultSetter(Class* owner, std::string name, 931cb0ef41Sopenharmony_ci std::string parameter_type, 941cb0ef41Sopenharmony_ci std::string parameter_name) { 951cb0ef41Sopenharmony_ci Function setter(owner, std::move(name)); 961cb0ef41Sopenharmony_ci setter.SetReturnType("void"); 971cb0ef41Sopenharmony_ci setter.AddParameter(std::move(parameter_type), std::move(parameter_name)); 981cb0ef41Sopenharmony_ci setter.SetInline(); 991cb0ef41Sopenharmony_ci return setter; 1001cb0ef41Sopenharmony_ci } 1011cb0ef41Sopenharmony_ci 1021cb0ef41Sopenharmony_ci void SetFlag(FunctionFlag flag, bool value = true) { 1031cb0ef41Sopenharmony_ci if (value) { 1041cb0ef41Sopenharmony_ci flags_ = flags_ | flag; 1051cb0ef41Sopenharmony_ci } else { 1061cb0ef41Sopenharmony_ci flags_ = flags_.without(flag); 1071cb0ef41Sopenharmony_ci } 1081cb0ef41Sopenharmony_ci } 1091cb0ef41Sopenharmony_ci void SetFlags(base::Flags<FunctionFlag> flags, bool value = true) { 1101cb0ef41Sopenharmony_ci if (value) { 1111cb0ef41Sopenharmony_ci flags_ |= flags; 1121cb0ef41Sopenharmony_ci } else { 1131cb0ef41Sopenharmony_ci flags_ &= ~flags; 1141cb0ef41Sopenharmony_ci } 1151cb0ef41Sopenharmony_ci } 1161cb0ef41Sopenharmony_ci bool HasFlag(FunctionFlag flag) const { return (flags_ & flag) == flag; } 1171cb0ef41Sopenharmony_ci#define ACCESSOR(name, value) \ 1181cb0ef41Sopenharmony_ci void Set##name(bool v = true) { SetFlag(k##name, v); } \ 1191cb0ef41Sopenharmony_ci bool Is##name() const { return HasFlag(k##name); } 1201cb0ef41Sopenharmony_ci FUNCTION_FLAG_LIST(ACCESSOR) 1211cb0ef41Sopenharmony_ci#undef ACCESSOR 1221cb0ef41Sopenharmony_ci 1231cb0ef41Sopenharmony_ci void SetDescription(std::string description) { 1241cb0ef41Sopenharmony_ci description_ = std::move(description); 1251cb0ef41Sopenharmony_ci } 1261cb0ef41Sopenharmony_ci void SetName(std::string name) { name_ = std::move(name); } 1271cb0ef41Sopenharmony_ci void SetReturnType(std::string return_type) { 1281cb0ef41Sopenharmony_ci return_type_ = std::move(return_type); 1291cb0ef41Sopenharmony_ci } 1301cb0ef41Sopenharmony_ci void AddParameter(std::string type, std::string name = {}, 1311cb0ef41Sopenharmony_ci std::string default_value = {}) { 1321cb0ef41Sopenharmony_ci parameters_.emplace_back(std::move(type), std::move(name), 1331cb0ef41Sopenharmony_ci std::move(default_value)); 1341cb0ef41Sopenharmony_ci } 1351cb0ef41Sopenharmony_ci void InsertParameter(int index, std::string type, std::string name = {}, 1361cb0ef41Sopenharmony_ci std::string default_value = {}) { 1371cb0ef41Sopenharmony_ci DCHECK_GE(index, 0); 1381cb0ef41Sopenharmony_ci DCHECK_LE(index, parameters_.size()); 1391cb0ef41Sopenharmony_ci parameters_.insert( 1401cb0ef41Sopenharmony_ci parameters_.begin() + index, 1411cb0ef41Sopenharmony_ci Parameter(std::move(type), std::move(name), std::move(default_value))); 1421cb0ef41Sopenharmony_ci } 1431cb0ef41Sopenharmony_ci std::vector<Parameter> GetParameters() const { return parameters_; } 1441cb0ef41Sopenharmony_ci std::vector<std::string> GetParameterNames() const { 1451cb0ef41Sopenharmony_ci std::vector<std::string> names; 1461cb0ef41Sopenharmony_ci std::transform(parameters_.begin(), parameters_.end(), 1471cb0ef41Sopenharmony_ci std::back_inserter(names), 1481cb0ef41Sopenharmony_ci [](const Parameter& p) { return p.name; }); 1491cb0ef41Sopenharmony_ci return names; 1501cb0ef41Sopenharmony_ci } 1511cb0ef41Sopenharmony_ci 1521cb0ef41Sopenharmony_ci static constexpr int kAutomaticIndentation = -1; 1531cb0ef41Sopenharmony_ci void PrintDeclaration(std::ostream& stream, 1541cb0ef41Sopenharmony_ci int indentation = kAutomaticIndentation) const; 1551cb0ef41Sopenharmony_ci void PrintDefinition(std::ostream& stream, 1561cb0ef41Sopenharmony_ci const std::function<void(std::ostream&)>& builder, 1571cb0ef41Sopenharmony_ci int indentation = 0) const; 1581cb0ef41Sopenharmony_ci void PrintInlineDefinition(std::ostream& stream, 1591cb0ef41Sopenharmony_ci const std::function<void(std::ostream&)>& builder, 1601cb0ef41Sopenharmony_ci int indentation = 2) const; 1611cb0ef41Sopenharmony_ci void PrintBeginDefinition(std::ostream& stream, int indentation = 0) const; 1621cb0ef41Sopenharmony_ci void PrintEndDefinition(std::ostream& stream, int indentation = 0) const; 1631cb0ef41Sopenharmony_ci 1641cb0ef41Sopenharmony_ci protected: 1651cb0ef41Sopenharmony_ci void PrintDeclarationHeader(std::ostream& stream, int indentation) const; 1661cb0ef41Sopenharmony_ci 1671cb0ef41Sopenharmony_ci private: 1681cb0ef41Sopenharmony_ci SourcePosition pos_; 1691cb0ef41Sopenharmony_ci Class* owning_class_; 1701cb0ef41Sopenharmony_ci std::string description_; 1711cb0ef41Sopenharmony_ci std::string name_; 1721cb0ef41Sopenharmony_ci std::string return_type_; 1731cb0ef41Sopenharmony_ci std::vector<Parameter> parameters_; 1741cb0ef41Sopenharmony_ci base::Flags<FunctionFlag> flags_; 1751cb0ef41Sopenharmony_ci}; 1761cb0ef41Sopenharmony_ci 1771cb0ef41Sopenharmony_ciDEFINE_OPERATORS_FOR_FLAGS(base::Flags<Function::FunctionFlag>) 1781cb0ef41Sopenharmony_ci#undef FUNCTION_FLAG_LIST 1791cb0ef41Sopenharmony_ci 1801cb0ef41Sopenharmony_ciclass File { 1811cb0ef41Sopenharmony_ci public: 1821cb0ef41Sopenharmony_ci explicit File(std::ostream& stream) : stream_(&stream) {} 1831cb0ef41Sopenharmony_ci 1841cb0ef41Sopenharmony_ci void BeginIncludeGuard(const std::string& name); 1851cb0ef41Sopenharmony_ci void EndIncludeGuard(const std::string& name); 1861cb0ef41Sopenharmony_ci void BeginNamespace(std::string name); 1871cb0ef41Sopenharmony_ci void BeginNamespace(std::string name0, std::string name1); 1881cb0ef41Sopenharmony_ci void EndNamespace(const std::string& name); 1891cb0ef41Sopenharmony_ci void EndNamespace(const std::string& name0, const std::string& name1); 1901cb0ef41Sopenharmony_ci 1911cb0ef41Sopenharmony_ci void AddInclude(std::string include) { includes_.insert(std::move(include)); } 1921cb0ef41Sopenharmony_ci 1931cb0ef41Sopenharmony_ci template <typename T> 1941cb0ef41Sopenharmony_ci File& operator<<(const T& value) { 1951cb0ef41Sopenharmony_ci s() << value; 1961cb0ef41Sopenharmony_ci return *this; 1971cb0ef41Sopenharmony_ci } 1981cb0ef41Sopenharmony_ci 1991cb0ef41Sopenharmony_ci protected: 2001cb0ef41Sopenharmony_ci std::ostream& s() { return *stream_; } 2011cb0ef41Sopenharmony_ci 2021cb0ef41Sopenharmony_ci private: 2031cb0ef41Sopenharmony_ci std::ostream* stream_; 2041cb0ef41Sopenharmony_ci std::set<std::string> includes_; 2051cb0ef41Sopenharmony_ci std::stack<std::string> namespaces_; 2061cb0ef41Sopenharmony_ci}; 2071cb0ef41Sopenharmony_ci 2081cb0ef41Sopenharmony_ciclass IncludeGuardScope { 2091cb0ef41Sopenharmony_ci public: 2101cb0ef41Sopenharmony_ci explicit IncludeGuardScope(File* file, std::string name) 2111cb0ef41Sopenharmony_ci : file_(file), name_(std::move(name)) { 2121cb0ef41Sopenharmony_ci file_->BeginIncludeGuard(name_); 2131cb0ef41Sopenharmony_ci } 2141cb0ef41Sopenharmony_ci IncludeGuardScope(const IncludeGuardScope&) = delete; 2151cb0ef41Sopenharmony_ci IncludeGuardScope(IncludeGuardScope&& other) V8_NOEXCEPT : file_(nullptr), 2161cb0ef41Sopenharmony_ci name_() { 2171cb0ef41Sopenharmony_ci std::swap(file_, other.file_); 2181cb0ef41Sopenharmony_ci std::swap(name_, other.name_); 2191cb0ef41Sopenharmony_ci } 2201cb0ef41Sopenharmony_ci ~IncludeGuardScope() { 2211cb0ef41Sopenharmony_ci if (file_) { 2221cb0ef41Sopenharmony_ci file_->EndIncludeGuard(name_); 2231cb0ef41Sopenharmony_ci } 2241cb0ef41Sopenharmony_ci } 2251cb0ef41Sopenharmony_ci IncludeGuardScope& operator=(const IncludeGuardScope&) = delete; 2261cb0ef41Sopenharmony_ci IncludeGuardScope& operator=(IncludeGuardScope&& other) V8_NOEXCEPT { 2271cb0ef41Sopenharmony_ci if (this != &other) { 2281cb0ef41Sopenharmony_ci DCHECK_NULL(file_); 2291cb0ef41Sopenharmony_ci DCHECK(name_.empty()); 2301cb0ef41Sopenharmony_ci std::swap(file_, other.file_); 2311cb0ef41Sopenharmony_ci std::swap(name_, other.name_); 2321cb0ef41Sopenharmony_ci } 2331cb0ef41Sopenharmony_ci return *this; 2341cb0ef41Sopenharmony_ci } 2351cb0ef41Sopenharmony_ci 2361cb0ef41Sopenharmony_ci private: 2371cb0ef41Sopenharmony_ci File* file_; 2381cb0ef41Sopenharmony_ci std::string name_; 2391cb0ef41Sopenharmony_ci}; 2401cb0ef41Sopenharmony_ci 2411cb0ef41Sopenharmony_ci} // namespace cpp 2421cb0ef41Sopenharmony_ci} // namespace torque 2431cb0ef41Sopenharmony_ci} // namespace internal 2441cb0ef41Sopenharmony_ci} // namespace v8 2451cb0ef41Sopenharmony_ci 2461cb0ef41Sopenharmony_ci#endif // V8_TORQUE_CPP_BUILDER_H_ 247