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