1
2
3
4
5
6 #include <sngcm/ast/Function.hpp>
7 #include <sngcm/ast/Visitor.hpp>
8
9 namespace sngcm { namespace ast {
10
11 FunctionNode::FunctionNode(const Span& span_, const boost::uuids::uuid& moduleId_) : Node(NodeType::functionNode, span_, moduleId_), specifiers(Specifiers::none), returnTypeExpr(), groupId(),
12 parameters(), body(), bodySource(), programMain(false)
13 {
14 }
15
16 FunctionNode::FunctionNode(NodeType nodeType_, const Span& span_, const boost::uuids::uuid& moduleId_) : Node(nodeType_, span_, moduleId_), specifiers(Specifiers::none), returnTypeExpr(), groupId(),
17 parameters(), body(), bodySource(), programMain(false)
18 {
19 }
20
21 FunctionNode::FunctionNode(const Span& span_, const boost::uuids::uuid& moduleId_, Specifiers specifiers_, Node* returnTypeExpr_, const std::u32string& groupId_, AttributesNode* attributes_) :
22 Node(NodeType::functionNode, span_, moduleId_), specifiers(specifiers_), returnTypeExpr(returnTypeExpr_), groupId(groupId_), templateParameters(), parameters(), body(), bodySource(), attributes(attributes_), programMain(false)
23 {
24 if (returnTypeExpr)
25 {
26 returnTypeExpr->SetParent(this);
27 }
28 }
29
30 FunctionNode::FunctionNode(NodeType nodeType_, const Span& span_, const boost::uuids::uuid& moduleId_, Specifiers specifiers_, Node* returnTypeExpr_, const std::u32string& groupId_, AttributesNode* attributes_) :
31 Node(nodeType_, span_, moduleId_), specifiers(specifiers_), returnTypeExpr(returnTypeExpr_), groupId(groupId_), templateParameters(), parameters(), body(), bodySource(), attributes(attributes_), programMain(false)
32 {
33 if (returnTypeExpr)
34 {
35 returnTypeExpr->SetParent(this);
36 }
37 }
38
39 Node* FunctionNode::Clone(CloneContext& cloneContext) const
40 {
41 AttributesNode* clonedAttributes = nullptr;
42 if (attributes)
43 {
44 clonedAttributes = static_cast<AttributesNode*>(attributes->Clone(cloneContext));
45 }
46 Node* clonedReturnTypeExpr = nullptr;
47 if (returnTypeExpr)
48 {
49 clonedReturnTypeExpr = returnTypeExpr->Clone(cloneContext);
50 }
51 FunctionNode* clone = new FunctionNode(GetSpan(), ModuleId(), specifiers, clonedReturnTypeExpr, groupId, clonedAttributes);
52 if (!cloneContext.InstantiateFunctionNode())
53 {
54 int nt = templateParameters.Count();
55 for (int i = 0; i < nt; ++i)
56 {
57 clone->AddTemplateParameter(static_cast<TemplateParameterNode*>(templateParameters[i]->Clone(cloneContext)));
58 }
59 }
60 int np = parameters.Count();
61 for (int i = 0; i < np; ++i)
62 {
63 clone->AddParameter(static_cast<ParameterNode*>(parameters[i]->Clone(cloneContext)));
64 }
65 if (body)
66 {
67 if (cloneContext.InstantiateClassNode())
68 {
69 CloneContext bodyCloneContext;
70 clone->SetBodySource(static_cast<CompoundStatementNode*>(body->Clone(bodyCloneContext)));
71 }
72 else
73 {
74 clone->SetBody(static_cast<CompoundStatementNode*>(body->Clone(cloneContext)));
75 }
76 }
77 if (whereConstraint)
78 {
79 clone->SetConstraint(static_cast<WhereConstraintNode*>(whereConstraint->Clone(cloneContext)));
80 }
81 clone->SetGroupIdSpan(groupIdSpan);
82 clone->SetSpecifierSpan(specifierSpan);
83 return clone;
84 }
85
86 void FunctionNode::CloneContent(FunctionNode* clone, CloneContext& cloneContext) const
87 {
88 if (attributes)
89 {
90 AttributesNode* clonedAttributes = static_cast<AttributesNode*>(attributes->Clone(cloneContext));
91 clone->attributes.reset(clonedAttributes);
92 }
93 clone->specifiers = specifiers;
94 Node* clonedReturnTypeExpr = nullptr;
95 if (returnTypeExpr)
96 {
97 clone->SetReturnTypeExpr(returnTypeExpr->Clone(cloneContext));
98 }
99 clone->groupId = groupId;
100 int nt = templateParameters.Count();
101 for (int i = 0; i < nt; ++i)
102 {
103 clone->AddTemplateParameter(static_cast<TemplateParameterNode*>(templateParameters[i]->Clone(cloneContext)));
104 }
105 int np = parameters.Count();
106 for (int i = 0; i < np; ++i)
107 {
108 clone->AddParameter(static_cast<ParameterNode*>(parameters[i]->Clone(cloneContext)));
109 }
110 if (body)
111 {
112 if (cloneContext.InstantiateClassNode())
113 {
114 CloneContext bodyCloneContext;
115 clone->SetBodySource(static_cast<CompoundStatementNode*>(body->Clone(bodyCloneContext)));
116 }
117 else
118 {
119 clone->SetBody(static_cast<CompoundStatementNode*>(body->Clone(cloneContext)));
120 }
121 }
122 if (whereConstraint)
123 {
124 clone->SetConstraint(static_cast<WhereConstraintNode*>(whereConstraint->Clone(cloneContext)));
125 }
126 clone->SetGroupIdSpan(groupIdSpan);
127 clone->SetSpecifierSpan(specifierSpan);
128 }
129
130 void FunctionNode::Accept(Visitor& visitor)
131 {
132 visitor.Visit(*this);
133 }
134
135 void FunctionNode::Write(AstWriter& writer)
136 {
137 Node::Write(writer);
138 bool hasAttributes = attributes != nullptr;
139 writer.GetBinaryWriter().Write(hasAttributes);
140 if (hasAttributes)
141 {
142 writer.Write(attributes.get());
143 }
144 writer.Write(specifiers);
145 bool hasReturnTypeExpr = returnTypeExpr != nullptr;
146 writer.GetBinaryWriter().Write(hasReturnTypeExpr);
147 if (hasReturnTypeExpr)
148 {
149 writer.Write(returnTypeExpr.get());
150 }
151 writer.GetBinaryWriter().Write(groupId);
152 templateParameters.Write(writer);
153 parameters.Write(writer);
154 bool hasConstraint = whereConstraint != nullptr;
155 writer.GetBinaryWriter().Write(hasConstraint);
156 if (hasConstraint)
157 {
158 writer.Write(whereConstraint.get());
159 }
160 bool hasBody = body != nullptr;
161 writer.GetBinaryWriter().Write(hasBody);
162 if (hasBody)
163 {
164 writer.Write(body.get());
165 }
166 bool hasBodySource = bodySource != nullptr;
167 writer.GetBinaryWriter().Write(hasBodySource);
168 if (hasBodySource)
169 {
170 writer.Write(bodySource.get());
171 }
172 bool convertExternal = ModuleId() == writer.SpanConversionModuleId();
173 writer.Write(groupIdSpan, convertExternal);
174 writer.Write(specifierSpan, convertExternal);
175 }
176
177 void FunctionNode::Read(AstReader& reader)
178 {
179 Node::Read(reader);
180 bool hasAttributes = reader.GetBinaryReader().ReadBool();
181 if (hasAttributes)
182 {
183 attributes.reset(reader.ReadAttributesNode());
184 }
185 specifiers = reader.ReadSpecifiers();
186 bool hasReturnTypeExpr = reader.GetBinaryReader().ReadBool();
187 if (hasReturnTypeExpr)
188 {
189 returnTypeExpr.reset(reader.ReadNode());
190 returnTypeExpr->SetParent(this);
191 }
192 groupId = reader.GetBinaryReader().ReadUtf32String();
193 templateParameters.Read(reader);
194 templateParameters.SetParent(this);
195 parameters.Read(reader);
196 parameters.SetParent(this);
197 bool hasConstraint = reader.GetBinaryReader().ReadBool();
198 if (hasConstraint)
199 {
200 whereConstraint.reset(reader.ReadWhereConstraintNode());
201 }
202 bool hasBody = reader.GetBinaryReader().ReadBool();
203 if (hasBody)
204 {
205 body.reset(reader.ReadCompoundStatementNode());
206 body->SetParent(this);
207 }
208 bool hasBodySource = reader.GetBinaryReader().ReadBool();
209 if (hasBodySource)
210 {
211 bodySource.reset(reader.ReadCompoundStatementNode());
212 bodySource->SetParent(this);
213 }
214 groupIdSpan = reader.ReadSpan();
215 specifierSpan = reader.ReadSpan();
216 }
217
218 void FunctionNode::AddTemplateParameter(TemplateParameterNode* templateParameter)
219 {
220 templateParameter->SetParent(this);
221 templateParameters.Add(templateParameter);
222 }
223
224 void FunctionNode::AddParameter(ParameterNode* parameter)
225 {
226 parameter->SetParent(this);
227 parameters.Add(parameter);
228 }
229
230 void FunctionNode::SwitchToBody()
231 {
232 if (bodySource && !body)
233 {
234 SetBody(bodySource.release());
235 }
236 }
237
238 void FunctionNode::SetReturnTypeExpr(Node* returnTypeExpr_)
239 {
240 returnTypeExpr.reset(returnTypeExpr_);
241 returnTypeExpr->SetParent(returnTypeExpr_);
242 }
243
244 void FunctionNode::SetSpecifiers(Specifiers specifiers_)
245 {
246 specifiers = specifiers_;
247 }
248
249 void FunctionNode::SetConstraint(WhereConstraintNode* whereConstraint_)
250 {
251 whereConstraint.reset(whereConstraint_);
252 whereConstraint->SetParent(this);
253 }
254
255 void FunctionNode::SetBody(CompoundStatementNode* body_)
256 {
257 body.reset(body_);
258 body->SetParent(this);
259 }
260
261 void FunctionNode::SetBodySource(CompoundStatementNode* bodySource_)
262 {
263 bodySource.reset(bodySource_);
264 bodySource->SetParent(this);
265 }
266
267 FunctionPtrNode::FunctionPtrNode(const Span& span_, const boost::uuids::uuid& moduleId_) : Node(NodeType::functionPtrNode, span_, moduleId_), boundExpression(nullptr)
268 {
269 }
270
271 Node* FunctionPtrNode::Clone(CloneContext& cloneContext) const
272 {
273 throw std::runtime_error("internal error: function ptr node cannot be cloned");
274 }
275
276 void FunctionPtrNode::Accept(Visitor& visitor)
277 {
278 visitor.Visit(*this);
279 }
280
281 } }