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