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