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