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 #include "src/torque/cpp-builder.h"
6 
7 namespace v8 {
8 namespace internal {
9 namespace torque {
10 namespace cpp {
11 
PrintDeclarationHeader(std::ostream& stream, int indentation) const12 void Function::PrintDeclarationHeader(std::ostream& stream,
13                                       int indentation) const {
14   if (!description_.empty()) {
15     stream << std::string(indentation, ' ') << "// " << description_ << "\n";
16   }
17   stream << std::string(indentation, ' ') << "// " << pos_ << "\n";
18   stream << std::string(indentation, ' ');
19   if (IsExport()) stream << "V8_EXPORT_PRIVATE ";
20   if (IsV8Inline())
21     stream << "V8_INLINE ";
22   else if (IsInline())
23     stream << "inline ";
24   if (IsStatic()) stream << "static ";
25   if (IsConstexpr()) stream << "constexpr ";
26   stream << return_type_ << " " << name_ << "(";
27   bool first = true;
28   for (const auto& p : parameters_) {
29     if (!first) stream << ", ";
30     stream << p.type;
31     if (!p.name.empty()) stream << " " << p.name;
32     if (!p.default_value.empty()) stream << " = " << p.default_value;
33     first = false;
34   }
35   stream << ")";
36   if (IsConst()) stream << " const";
37 }
38 
PrintDeclaration(std::ostream& stream, int indentation) const39 void Function::PrintDeclaration(std::ostream& stream, int indentation) const {
40   if (indentation == kAutomaticIndentation) {
41     indentation = owning_class_ ? 2 : 0;
42   }
43   PrintDeclarationHeader(stream, indentation);
44   stream << ";\n";
45 }
46 
PrintDefinition( std::ostream& stream, const std::function<void(std::ostream&)>& builder, int indentation) const47 void Function::PrintDefinition(
48     std::ostream& stream, const std::function<void(std::ostream&)>& builder,
49     int indentation) const {
50   PrintBeginDefinition(stream, indentation);
51   if (builder) {
52     builder(stream);
53   }
54   PrintEndDefinition(stream, indentation);
55 }
56 
PrintInlineDefinition( std::ostream& stream, const std::function<void(std::ostream&)>& builder, int indentation) const57 void Function::PrintInlineDefinition(
58     std::ostream& stream, const std::function<void(std::ostream&)>& builder,
59     int indentation) const {
60   PrintDeclarationHeader(stream, indentation);
61   stream << " {\n";
62   if (builder) {
63     builder(stream);
64   }
65   PrintEndDefinition(stream, indentation);
66 }
67 
PrintBeginDefinition(std::ostream& stream, int indentation) const68 void Function::PrintBeginDefinition(std::ostream& stream,
69                                     int indentation) const {
70   stream << std::string(indentation, ' ') << "// " << pos_ << "\n";
71   std::string scope;
72   if (owning_class_) {
73     scope = owning_class_->GetName();
74     const auto class_template_parameters =
75         owning_class_->GetTemplateParameters();
76     if (!class_template_parameters.empty()) {
77       stream << std::string(indentation, ' ');
78       stream << "template<";
79       scope += "<";
80       bool first = true;
81       for (const auto& p : class_template_parameters) {
82         if (!first) {
83           stream << ", ";
84           scope += ", ";
85         }
86         if (p.type.empty()) {
87           stream << "class " << p.name;
88         } else {
89           stream << p.type << " " << p.name;
90         }
91         scope += p.name;
92         first = false;
93       }
94       stream << ">\n";
95       scope += ">";
96     }
97     scope += "::";
98   }
99   stream << std::string(indentation, ' ') << return_type_ << " " << scope
100          << name_ << "(";
101   bool first = true;
102   for (const auto& p : parameters_) {
103     if (!first) stream << ", ";
104     stream << p.type;
105     if (!p.name.empty()) stream << " " << p.name;
106     first = false;
107   }
108   stream << ")";
109   if (IsConst()) {
110     stream << " const";
111   }
112   stream << " {\n";
113 }
114 
PrintEndDefinition(std::ostream& stream, int indentation) const115 void Function::PrintEndDefinition(std::ostream& stream, int indentation) const {
116   stream << std::string(indentation, ' ');
117   stream << "}\n\n";
118 }
119 
BeginIncludeGuard(const std::string& name)120 void File::BeginIncludeGuard(const std::string& name) {
121   s() << "#ifndef " << name
122       << "\n"
123          "#define "
124       << name << "\n\n";
125 }
126 
EndIncludeGuard(const std::string& name)127 void File::EndIncludeGuard(const std::string& name) {
128   s() << "#endif // " << name << "\n";
129 }
130 
BeginNamespace(std::string name)131 void File::BeginNamespace(std::string name) {
132   DCHECK(!name.empty());
133   DCHECK_EQ(name.find(':'), std::string::npos);
134   s() << "namespace " << name << " {\n";
135   namespaces_.push(std::move(name));
136 }
137 
BeginNamespace(std::string name0, std::string name1)138 void File::BeginNamespace(std::string name0, std::string name1) {
139   BeginNamespace(name0);
140   BeginNamespace(name1);
141 }
142 
EndNamespace(const std::string& name)143 void File::EndNamespace(const std::string& name) {
144   DCHECK(!namespaces_.empty());
145   DCHECK_EQ(namespaces_.top(), name);
146   s() << "} // namespace " << namespaces_.top() << "\n";
147   namespaces_.pop();
148 }
149 
EndNamespace(const std::string& name0, const std::string& name1)150 void File::EndNamespace(const std::string& name0, const std::string& name1) {
151   EndNamespace(name1);
152   EndNamespace(name0);
153 }
154 
155 }  // namespace cpp
156 }  // namespace torque
157 }  // namespace internal
158 }  // namespace v8
159