1
2
3
4
5
6 #include <cpp2cm/cpp2cm/Converter.hpp>
7 #include <cpp2cm/cpp2cm/Args.hpp>
8 #include <sngcpp/ast/SourceFile.hpp>
9 #include <sngcpp/ast/Class.hpp>
10 #include <sngcpp/ast/Namespace.hpp>
11 #include <sngcpp/symbols/ParameterSymbol.hpp>
12 #include <sngcpp/symbols/VariableSymbol.hpp>
13 #include <sngcpp/symbols/ClassTemplateSpecializationSymbol.hpp>
14 #include <sngcm/ast/SourceWriter.hpp>
15 #include <sngcm/ast/CompileUnit.hpp>
16 #include <sngcm/ast/Identifier.hpp>
17 #include <sngcm/ast/Function.hpp>
18 #include <sngcm/ast/Class.hpp>
19 #include <sngcm/ast/Literal.hpp>
20 #include <sngcm/ast/Expression.hpp>
21 #include <sngcm/ast/TypeExpr.hpp>
22 #include <sngcm/ast/GlobalVariable.hpp>
23 #include <sngcm/ast/Comment.hpp>
24 #include <sngcm/ast/Constant.hpp>
25 #include <sngcm/ast/Enumeration.hpp>
26 #include <soulng/util/Path.hpp>
27 #include <soulng/util/Unicode.hpp>
28 #include <fstream>
29 #include <iostream>
30
31 namespace cpp2cm {
32
33 const char* Cpp2CmVersion()
34 {
35 return "1.0.0";
36 }
37
38 using namespace soulng::util;
39 using namespace soulng::unicode;
40 using soulng::lexer::Span;
41
42
43
44 sngcm::ast::NodeType commonType[15][15] =
45 {
46
47 {
48 sngcm::ast::NodeType::boolNode, sngcm::ast::NodeType::sbyteNode, sngcm::ast::NodeType::byteNode, sngcm::ast::NodeType::shortNode,
49 sngcm::ast::NodeType::ushortNode, sngcm::ast::NodeType::intNode, sngcm::ast::NodeType::uintNode, sngcm::ast::NodeType::longNode,
50 sngcm::ast::NodeType::ulongNode, sngcm::ast::NodeType::floatNode, sngcm::ast::NodeType::doubleNode, sngcm::ast::NodeType::charNode,
51 sngcm::ast::NodeType::wcharNode, sngcm::ast::NodeType::ucharNode, sngcm::ast::NodeType::voidNode
52 }
53
54 {
55 sngcm::ast::NodeType::sbyteNode, sngcm::ast::NodeType::sbyteNode, sngcm::ast::NodeType::shortNode, sngcm::ast::NodeType::shortNode,
56 sngcm::ast::NodeType::intNode, sngcm::ast::NodeType::intNode, sngcm::ast::NodeType::longNode, sngcm::ast::NodeType::longNode,
57 sngcm::ast::NodeType::ulongNode, sngcm::ast::NodeType::floatNode, sngcm::ast::NodeType::doubleNode, sngcm::ast::NodeType::charNode,
58 sngcm::ast::NodeType::wcharNode, sngcm::ast::NodeType::ucharNode, sngcm::ast::NodeType::voidNode
59 }
60
61 {
62 sngcm::ast::NodeType::byteNode, sngcm::ast::NodeType::shortNode, sngcm::ast::NodeType::byteNode, sngcm::ast::NodeType::shortNode,
63 sngcm::ast::NodeType::ushortNode, sngcm::ast::NodeType::intNode, sngcm::ast::NodeType::uintNode, sngcm::ast::NodeType::longNode,
64 sngcm::ast::NodeType::ulongNode, sngcm::ast::NodeType::floatNode, sngcm::ast::NodeType::doubleNode, sngcm::ast::NodeType::charNode,
65 sngcm::ast::NodeType::wcharNode, sngcm::ast::NodeType::ucharNode, sngcm::ast::NodeType::voidNode
66 }
67
68 {
69 sngcm::ast::NodeType::shortNode, sngcm::ast::NodeType::shortNode, sngcm::ast::NodeType::shortNode, sngcm::ast::NodeType::shortNode,
70 sngcm::ast::NodeType::intNode, sngcm::ast::NodeType::intNode, sngcm::ast::NodeType::longNode, sngcm::ast::NodeType::longNode,
71 sngcm::ast::NodeType::ulongNode, sngcm::ast::NodeType::floatNode, sngcm::ast::NodeType::doubleNode, sngcm::ast::NodeType::charNode,
72 sngcm::ast::NodeType::wcharNode, sngcm::ast::NodeType::ucharNode, sngcm::ast::NodeType::voidNode
73 }
74
75 {
76 sngcm::ast::NodeType::ushortNode, sngcm::ast::NodeType::ushortNode, sngcm::ast::NodeType::ushortNode, sngcm::ast::NodeType::intNode,
77 sngcm::ast::NodeType::ushortNode, sngcm::ast::NodeType::intNode, sngcm::ast::NodeType::uintNode, sngcm::ast::NodeType::longNode,
78 sngcm::ast::NodeType::ulongNode, sngcm::ast::NodeType::floatNode, sngcm::ast::NodeType::doubleNode, sngcm::ast::NodeType::charNode,
79 sngcm::ast::NodeType::wcharNode, sngcm::ast::NodeType::ucharNode, sngcm::ast::NodeType::voidNode
80 }
81
82 {
83 sngcm::ast::NodeType::intNode, sngcm::ast::NodeType::intNode, sngcm::ast::NodeType::intNode, sngcm::ast::NodeType::intNode,
84 sngcm::ast::NodeType::intNode, sngcm::ast::NodeType::intNode, sngcm::ast::NodeType::longNode, sngcm::ast::NodeType::longNode,
85 sngcm::ast::NodeType::ulongNode, sngcm::ast::NodeType::floatNode, sngcm::ast::NodeType::doubleNode, sngcm::ast::NodeType::charNode,
86 sngcm::ast::NodeType::wcharNode, sngcm::ast::NodeType::ucharNode, sngcm::ast::NodeType::voidNode
87 }
88
89 {
90 sngcm::ast::NodeType::uintNode, sngcm::ast::NodeType::uintNode, sngcm::ast::NodeType::uintNode, sngcm::ast::NodeType::longNode,
91 sngcm::ast::NodeType::uintNode, sngcm::ast::NodeType::longNode, sngcm::ast::NodeType::uintNode, sngcm::ast::NodeType::ulongNode,
92 sngcm::ast::NodeType::ulongNode, sngcm::ast::NodeType::floatNode, sngcm::ast::NodeType::doubleNode, sngcm::ast::NodeType::charNode,
93 sngcm::ast::NodeType::wcharNode, sngcm::ast::NodeType::ucharNode, sngcm::ast::NodeType::voidNode
94 }
95
96 {
97 sngcm::ast::NodeType::longNode, sngcm::ast::NodeType::longNode, sngcm::ast::NodeType::longNode, sngcm::ast::NodeType::longNode,
98 sngcm::ast::NodeType::longNode, sngcm::ast::NodeType::longNode, sngcm::ast::NodeType::longNode, sngcm::ast::NodeType::longNode,
99 sngcm::ast::NodeType::ulongNode, sngcm::ast::NodeType::floatNode, sngcm::ast::NodeType::doubleNode, sngcm::ast::NodeType::charNode,
100 sngcm::ast::NodeType::wcharNode, sngcm::ast::NodeType::ucharNode, sngcm::ast::NodeType::voidNode
101 }
102
103 {
104 sngcm::ast::NodeType::ulongNode, sngcm::ast::NodeType::ulongNode, sngcm::ast::NodeType::ulongNode, sngcm::ast::NodeType::ulongNode,
105 sngcm::ast::NodeType::ulongNode, sngcm::ast::NodeType::ulongNode, sngcm::ast::NodeType::ulongNode, sngcm::ast::NodeType::ulongNode,
106 sngcm::ast::NodeType::ulongNode, sngcm::ast::NodeType::floatNode, sngcm::ast::NodeType::doubleNode, sngcm::ast::NodeType::charNode,
107 sngcm::ast::NodeType::wcharNode, sngcm::ast::NodeType::ucharNode, sngcm::ast::NodeType::voidNode
108 }
109
110 {
111 sngcm::ast::NodeType::floatNode, sngcm::ast::NodeType::floatNode, sngcm::ast::NodeType::floatNode, sngcm::ast::NodeType::floatNode,
112 sngcm::ast::NodeType::floatNode, sngcm::ast::NodeType::floatNode, sngcm::ast::NodeType::floatNode, sngcm::ast::NodeType::floatNode,
113 sngcm::ast::NodeType::floatNode, sngcm::ast::NodeType::floatNode, sngcm::ast::NodeType::doubleNode, sngcm::ast::NodeType::charNode,
114 sngcm::ast::NodeType::wcharNode, sngcm::ast::NodeType::ucharNode, sngcm::ast::NodeType::voidNode
115 }
116
117 {
118 sngcm::ast::NodeType::doubleNode, sngcm::ast::NodeType::doubleNode, sngcm::ast::NodeType::doubleNode, sngcm::ast::NodeType::doubleNode,
119 sngcm::ast::NodeType::doubleNode, sngcm::ast::NodeType::doubleNode, sngcm::ast::NodeType::doubleNode, sngcm::ast::NodeType::doubleNode,
120 sngcm::ast::NodeType::doubleNode, sngcm::ast::NodeType::doubleNode, sngcm::ast::NodeType::doubleNode, sngcm::ast::NodeType::charNode,
121 sngcm::ast::NodeType::wcharNode, sngcm::ast::NodeType::ucharNode, sngcm::ast::NodeType::voidNode
122 }
123
124 {
125 sngcm::ast::NodeType::charNode, sngcm::ast::NodeType::charNode, sngcm::ast::NodeType::charNode, sngcm::ast::NodeType::charNode,
126 sngcm::ast::NodeType::charNode, sngcm::ast::NodeType::charNode, sngcm::ast::NodeType::charNode, sngcm::ast::NodeType::charNode,
127 sngcm::ast::NodeType::charNode, sngcm::ast::NodeType::charNode, sngcm::ast::NodeType::charNode, sngcm::ast::NodeType::charNode,
128 sngcm::ast::NodeType::wcharNode, sngcm::ast::NodeType::ucharNode, sngcm::ast::NodeType::voidNode
129 }
130
131 {
132 sngcm::ast::NodeType::wcharNode, sngcm::ast::NodeType::wcharNode, sngcm::ast::NodeType::wcharNode, sngcm::ast::NodeType::wcharNode,
133 sngcm::ast::NodeType::wcharNode, sngcm::ast::NodeType::wcharNode, sngcm::ast::NodeType::wcharNode, sngcm::ast::NodeType::wcharNode,
134 sngcm::ast::NodeType::wcharNode, sngcm::ast::NodeType::wcharNode, sngcm::ast::NodeType::wcharNode, sngcm::ast::NodeType::wcharNode,
135 sngcm::ast::NodeType::wcharNode, sngcm::ast::NodeType::ucharNode, sngcm::ast::NodeType::voidNode
136 }
137
138 {
139 sngcm::ast::NodeType::ucharNode, sngcm::ast::NodeType::ucharNode, sngcm::ast::NodeType::ucharNode, sngcm::ast::NodeType::ucharNode,
140 sngcm::ast::NodeType::ucharNode, sngcm::ast::NodeType::ucharNode, sngcm::ast::NodeType::ucharNode, sngcm::ast::NodeType::ucharNode,
141 sngcm::ast::NodeType::ucharNode, sngcm::ast::NodeType::ucharNode, sngcm::ast::NodeType::ucharNode, sngcm::ast::NodeType::ucharNode,
142 sngcm::ast::NodeType::ucharNode, sngcm::ast::NodeType::ucharNode, sngcm::ast::NodeType::voidNode
143 }
144
145 {
146 sngcm::ast::NodeType::voidNode, sngcm::ast::NodeType::voidNode, sngcm::ast::NodeType::voidNode, sngcm::ast::NodeType::voidNode,
147 sngcm::ast::NodeType::voidNode, sngcm::ast::NodeType::voidNode, sngcm::ast::NodeType::voidNode, sngcm::ast::NodeType::voidNode,
148 sngcm::ast::NodeType::voidNode, sngcm::ast::NodeType::voidNode, sngcm::ast::NodeType::voidNode, sngcm::ast::NodeType::voidNode,
149 sngcm::ast::NodeType::voidNode, sngcm::ast::NodeType::voidNode, sngcm::ast::NodeType::voidNode
150 }
151 };
152
153
154
155 std::std::vector<sngcpp::symbols::SimpleTypeSpecifier>GetSimpleTypeSpecifiers(sngcm::ast::NodeTypenodeType)
156 {
157 std::vector<sngcpp::symbols::SimpleTypeSpecifier> specifiers;
158 switch (nodeType)
159 {
160 case sngcm::ast::NodeType::boolNode: specifiers.push_back(sngcpp::symbols::SimpleTypeSpecifier::bool_); break;
161 case sngcm::ast::NodeType::sbyteNode: specifiers.push_back(sngcpp::symbols::SimpleTypeSpecifier::short_); break;
162 case sngcm::ast::NodeType::byteNode: specifiers.push_back(sngcpp::symbols::SimpleTypeSpecifier::unsigned_); specifiers.push_back(sngcpp::symbols::SimpleTypeSpecifier::short_); break;
163 case sngcm::ast::NodeType::shortNode: specifiers.push_back(sngcpp::symbols::SimpleTypeSpecifier::short_); break;
164 case sngcm::ast::NodeType::ushortNode: specifiers.push_back(sngcpp::symbols::SimpleTypeSpecifier::unsigned_); specifiers.push_back(sngcpp::symbols::SimpleTypeSpecifier::short_); break;
165 case sngcm::ast::NodeType::intNode: specifiers.push_back(sngcpp::symbols::SimpleTypeSpecifier::int_); break;
166 case sngcm::ast::NodeType::uintNode: specifiers.push_back(sngcpp::symbols::SimpleTypeSpecifier::unsigned_); specifiers.push_back(sngcpp::symbols::SimpleTypeSpecifier::int_); break;
167 case sngcm::ast::NodeType::longNode: specifiers.push_back(sngcpp::symbols::SimpleTypeSpecifier::long_); break;
168 case sngcm::ast::NodeType::ulongNode: specifiers.push_back(sngcpp::symbols::SimpleTypeSpecifier::unsigned_); specifiers.push_back(sngcpp::symbols::SimpleTypeSpecifier::long_); break;
169 case sngcm::ast::NodeType::floatNode: specifiers.push_back(sngcpp::symbols::SimpleTypeSpecifier::float_); break;
170 case sngcm::ast::NodeType::doubleNode: specifiers.push_back(sngcpp::symbols::SimpleTypeSpecifier::double_); break;
171 case sngcm::ast::NodeType::charNode: specifiers.push_back(sngcpp::symbols::SimpleTypeSpecifier::char_); break;
172 case sngcm::ast::NodeType::wcharNode: specifiers.push_back(sngcpp::symbols::SimpleTypeSpecifier::char16); break;
173 case sngcm::ast::NodeType::ucharNode: specifiers.push_back(sngcpp::symbols::SimpleTypeSpecifier::char32); break;
174 case sngcm::ast::NodeType::voidNode: specifiers.push_back(sngcpp::symbols::SimpleTypeSpecifier::void_); break;
175 }
176 return specifiers;
177 }
178
179 Converter::Converter(bool verbose_, const std::string& targetDir_, sngcpp::symbols::SymbolTable& symbolTable_, Map& map_,
180 const std::std::set<std::u32string>&excludedClasses_, conststd::std::set<std::u32string>&excludedFunctions_, NothrowList¬hrowList_):
181 verbose(verbose_), targetDir(targetDir_), symbolTable(symbolTable_), currentCompileUnit(nullptr), currentNamespace(nullptr), currentContext(nullptr), currentContainerNode(nullptr), map(map_),
182 addToNodes(false), type(nullptr), currentClassType(nullptr), currentEnumType(nullptr), assignment(false), empty(false), inFunctionBody(false),
183 assignmentStatement(false), rangeFor(false), catchDecl(false), statementContainer(StatementContainer::statements),
184 calledFunction(nullptr), excludedClasses(excludedClasses_), excludedFunctions(excludedFunctions_), parentCaseStatementNode(nullptr),
185 nothrowList(nothrowList_), nothrowFileItem(Item::Type::file, U"", false), nothrowClassItem(Item::Type::class_, U"", false), nothrowFunctionItem(Item::Type::function, U"", false)
186 {
187 }
188
189 void Converter::Write()
190 {
191 for (const auto& cu : compileUnits)
192 {
193 sngcm::ast::CombineNamespaces(*cu);
194 sngcm::ast::ArrangeClassMembers(*cu);
195 InsertNamespaceImports(cu.get());
196 std::ofstream sourceFile(cu->FilePath());
197 soulng::util::CodeFormatter formatter(sourceFile);
198 sngcm::ast::SourceWriter writer(formatter);
199 cu->Accept(writer);
200 std::u32string fileName = ToUtf32(Path::GetFileName(cu->FilePath()));
201 sourceFiles.Add(new SourceFile(fileName, cu->FilePath()));
202 }
203 }
204
205 void Converter::InsertNamespaceImports(sngcm::ast::CompileUnitNode* cu)
206 {
207 Context* context = &contextMap[cu];
208 int index = 0;
209 for (const auto& namespaceImport : context->namespaceImports)
210 {
211 cu->GlobalNs()->Members().Insert(index, new sngcm::ast::NamespaceImportNode(soulng::lexer::Span(), new sngcm::ast::IdentifierNode(soulng::lexer::Span(), namespaceImport)));
212 ++index;
213 }
214 }
215
216 void Converter::AddToContainer(int line, sngcm::ast::Node* node)
217 {
218 switch (currentContainerNode->GetNodeType())
219 {
220 case sngcm::ast::NodeType::namespaceNode:
221 {
222 sngcm::ast::NamespaceNode* ns = static_cast<sngcm::ast::NamespaceNode*>(currentContainerNode);
223 ns->AddMember(node);
224 break;
225 }
226 case sngcm::ast::NodeType::classNode:
227 {
228 sngcm::ast::ClassNode* cls = static_cast<sngcm::ast::ClassNode*>(currentContainerNode);
229 cls->AddMember(node);
230 break;
231 }
232 default:
233 {
234 WriteWarning(line, ": converter.AddToContainer: namespace or class container expected");
235 delete node;
236 return;
237 }
238 }
239 }
240
241 void Converter::AddStatement(int line, sngcm::ast::StatementNode* statement)
242 {
243 switch (statementContainer)
244 {
245 case StatementContainer::statements:
246 {
247 statementNodes.push_back(std::unique_ptr< sngcm::ast::StatementNode>(statement));
248 break;
249 }
250 case StatementContainer::latestCase:
251 {
252 if (caseStatementNodes.empty())
253 {
254 WriteWarning(line, "no case active");
255 statementNodes.push_back(std::unique_ptr< sngcm::ast::StatementNode>(statement));
256 }
257 else
258 {
259 caseStatementNodes.back()->AddStatement(statement);
260 }
261 break;
262 }
263 case StatementContainer::latestDefault:
264 {
265 if (!defaultStatement)
266 {
267 WriteWarning(line, "no default active");
268 statementNodes.push_back(std::unique_ptr< sngcm::ast::StatementNode>(statement));
269 }
270 else
271 {
272 defaultStatement->AddStatement(statement);
273 }
274 break;
275 }
276 }
277 }
278
279 void Converter::WriteWarning(int line, const std::string& message)
280 {
281 std::cerr << "warning: " << currentSourceFileName << ":" << line << ": " << message << std::endl;
282 }
283
284 void Converter::ConvertIdExpr(sngcpp::ast::Node* idExprNode)
285 {
286 mappedSymbolSequence.clear();
287 node.reset();
288 idExprNode->Accept(*this);
289 if (!node)
290 {
291 if (!mappedSymbolSequence.empty())
292 {
293 sngcpp::symbols::Symbol* symbol = mappedSymbolSequence.back();
294 if (symbol)
295 {
296 if (symbol->IsParameterSymbol())
297 {
298 node.reset(new sngcm::ast::IdentifierNode(soulng::lexer::Span(), symbol->Name()));
299 }
300 else if (symbol->IsVariableSymbol())
301 {
302 node.reset(new sngcm::ast::IdentifierNode(soulng::lexer::Span(), symbol->Name()));
303 }
304 else if (symbol->IsEnumeratorSymbol())
305 {
306 node.reset(new sngcm::ast::DotNode(soulng::lexer::Span(),
307 new sngcm::ast::IdentifierNode(soulng::lexer::Span(), symbol->Parent()->Name()), new sngcm::ast::IdentifierNode(soulng::lexer::Span(), symbol->Name())));
308 }
309 else if (symbol->IsClassGroupSymbol())
310 {
311 if (currentClassType)
312 {
313 sngcpp::symbols::ClassGroupSymbol* classGroupSymbol = static_cast<sngcpp::symbols::ClassGroupSymbol*>(symbol);
314 sngcpp::symbols::ClassTypeSymbol* classTypeSymbol = classGroupSymbol->GetClass(0);
315 if (currentClassType == classTypeSymbol)
316 {
317 node.reset(new sngcm::ast::ThisNode(soulng::lexer::Span()));
318 }
319 else if (currentClassType->BaseClasses().size() == 1 && currentClassType->BaseClasses().front() == classTypeSymbol)
320 {
321 node.reset(new sngcm::ast::BaseNode(soulng::lexer::Span()));
322 }
323 }
324 }
325 else if (symbol->IsTypeSymbol())
326 {
327 sngcpp::symbols::TypeSymbol* typeSymbol = static_cast<sngcpp::symbols::TypeSymbol*>(symbol);
328 sngxml::dom::Document* sourceXmlDoc = nullptr;
329 node.reset(map.MapType(typeSymbol, sourceXmlDoc));
330 type = typeSymbol;
331 }
332 else
333 {
334 int x = 0;
335 }
336 }
337 }
338 }
339 if (!node)
340 {
341 NotConverted(idExprNode->GetSpan().line, "id expression not converted");
342 }
343 }
344
345 void Converter::ConvertExpression(sngcpp::ast::Node* exprNode)
346 {
347 mappedSymbolSequence.clear();
348 node.reset();
349 if (exprNode->GetNodeType() == sngcpp::ast::NodeType::expressionInitializerNode)
350 {
351 sngcpp::ast::ExpressionInitializerNode* initializerNode = static_cast<sngcpp::ast::ExpressionInitializerNode*>(exprNode);
352 ConvertExpression(initializerNode->Child());
353 return;
354 }
355 else if (exprNode->GetNodeType() == sngcpp::ast::NodeType::assignmentInitializerNode)
356 {
357 sngcpp::ast::AssignmentInitializerNode* initializerNode = static_cast<sngcpp::ast::AssignmentInitializerNode*>(exprNode);
358 ConvertExpression(initializerNode->Child());
359 assignment = true;
360 return;
361 }
362 exprNode->Accept(*this);
363 if (!node)
364 {
365 if (!mappedSymbolSequence.empty())
366 {
367 sngcpp::symbols::Symbol* symbol = mappedSymbolSequence.back();
368 if (symbol)
369 {
370 if (symbol->IsParameterSymbol())
371 {
372 node.reset(new sngcm::ast::IdentifierNode(soulng::lexer::Span(), symbol->Name()));
373 type = symbol->GetType();
374 }
375 else if (symbol->IsVariableSymbol())
376 {
377 node.reset(new sngcm::ast::IdentifierNode(soulng::lexer::Span(), symbol->Name()));
378 type = symbol->GetType();
379 }
380 else if (symbol->IsEnumeratorSymbol())
381 {
382 node.reset(new sngcm::ast::DotNode(soulng::lexer::Span(),
383 new sngcm::ast::IdentifierNode(soulng::lexer::Span(), symbol->Parent()->Name()), new sngcm::ast::IdentifierNode(soulng::lexer::Span(), symbol->Name())));
384 type = symbol->GetType();
385 }
386 else if (symbol->IsFunctionGroupSymbol())
387 {
388 bool mapped = false;
389 if (calledFunction)
390 {
391 node.reset(map.MapFunctionSymbol(calledFunction, args));
392 if (node)
393 {
394 mapped = true;
395 if (calledFunction->ReturnType())
396 {
397 type = calledFunction->ReturnType();
398 }
399 else
400 {
401 type = nullptr;
402 }
403 }
404 }
405 if (!mapped)
406 {
407 if (calledFunction)
408 {
409 if (calledFunction->IsFunctionSymbol())
410 {
411 sngcpp::symbols::FunctionSymbol* calledFunctionSymbol = static_cast<sngcpp::symbols::FunctionSymbol*>(calledFunction);
412 if (calledFunctionSymbol->Parent()->IsClassTypeSymbol() &&
413 (calledFunctionSymbol->Specifiers() & sngcpp::ast::Specifier::static_) != sngcpp::ast::Specifier::none)
414 {
415 node.reset(new sngcm::ast::DotNode(soulng::lexer::Span(),
416 new sngcm::ast::IdentifierNode(soulng::lexer::Span(), calledFunctionSymbol->Parent()->Name()),
417 new sngcm::ast::IdentifierNode(soulng::lexer::Span(), symbol->Name())));
418 if (calledFunction->ReturnType())
419 {
420 type = calledFunction->ReturnType();
421 }
422 mapped = true;
423 }
424 }
425 }
426 if (!mapped)
427 {
428 node.reset(new sngcm::ast::IdentifierNode(soulng::lexer::Span(), symbol->Name()));
429 type = nullptr;
430 }
431 }
432 }
433 else if (symbol->IsTypeSymbol())
434 {
435 sngcpp::symbols::TypeSymbol* typeSymbol = static_cast<sngcpp::symbols::TypeSymbol*>(symbol);
436 sngxml::dom::Document* sourceXmlDoc = nullptr;
437 node.reset(map.MapType(typeSymbol, sourceXmlDoc));
438 type = typeSymbol;
439 }
440 else if (symbol->IsClassGroupSymbol())
441 {
442 sngcpp::symbols::ClassGroupSymbol* classGroupSymbol = static_cast<sngcpp::symbols::ClassGroupSymbol*>(symbol);
443 sngcpp::symbols::ClassTypeSymbol* classTypeSymbol = classGroupSymbol->GetClass(0);
444 sngxml::dom::Document* sourceXmlDoc = nullptr;
445 node.reset(map.MapType(classTypeSymbol, sourceXmlDoc));
446 type = classTypeSymbol;
447 }
448 else
449 {
450 int x = 0;
451 }
452 }
453 }
454 }
455 if (!node)
456 {
457 NotConverted(exprNode->GetSpan().line, "expression not converted");
458 }
459 if (addToNodes)
460 {
461 if (node->GetNodeType() != sngcm::ast::NodeType::emptyStatementNode)
462 {
463 nodes.Add(node.release());
464 }
465 node.reset(new sngcm::ast::EmptyStatementNode(soulng::lexer::Span()));
466 }
467 }
468
469 void Converter::NotConverted(int line, const std::string& message)
470 {
471 WriteWarning(line, message);
472 node.reset(new sngcm::ast::IdentifierNode(soulng::lexer::Span(), U"NOT_CONVERTED"));
473 type = nullptr;
474 }
475
476 void Converter::ConvertBooleanExpression(sngcpp::ast::Node* exprNode)
477 {
478 ConvertExpression(exprNode);
479 if (node)
480 {
481 sngcm::ast::NodeType nodeType = node->GetNodeType();
482 sngcpp::symbols::TypeSymbol* typeToConvert = type;
483 if (typeToConvert)
484 {
485 if (typeToConvert->IsDerivedTypeSymbol())
486 {
487 sngcpp::symbols::DerivedTypeSymbol* derivedType = static_cast<sngcpp::symbols::DerivedTypeSymbol*>(type);
488 for (sngcpp::symbols::Derivation derivation : derivedType->Derivations())
489 {
490 if (derivation == sngcpp::symbols::Derivation::ptr)
491 {
492 node.reset(new sngcm::ast::ParenthesizedExpressionNode(
493 soulng::lexer::Span(), new sngcm::ast::NotEqualNode(soulng::lexer::Span(), node.release(), new sngcm::ast::NullLiteralNode(soulng::lexer::Span()))));
494 return;
495 }
496 }
497 typeToConvert = derivedType->BaseType();
498 }
499 if (typeToConvert->IsSimpleTypeSymbol())
500 {
501 nodeType = map.MapSimpleType(static_cast<sngcpp::symbols::SimpleTypeSymbol*>(typeToConvert));
502 }
503 else if (typeToConvert->IsClassTemplateSpecializationSymbol())
504 {
505 sngcpp::symbols::ClassTemplateSpecializationSymbol* specialization = static_cast<sngcpp::symbols::ClassTemplateSpecializationSymbol*>(typeToConvert);
506 if (specialization->PrimaryClassTemplateSymbol()->FullName() == U"std::unique_ptr" || specialization->PrimaryClassTemplateSymbol()->FullName() == U"std::shared_ptr")
507 {
508 node.reset(new sngcm::ast::NotNode(soulng::lexer::Span(),
509 new sngcm::ast::InvokeNode(soulng::lexer::Span(), new sngcm::ast::DotNode(soulng::lexer::Span(), node.release(),
510 new sngcm::ast::IdentifierNode(soulng::lexer::Span(), U"IsNull")))));
511 return;
512 }
513 }
514 }
515 switch (nodeType)
516 {
517 case sngcm::ast::NodeType::sbyteNode:
518 {
519 node.reset(new sngcm::ast::ParenthesizedExpressionNode(
520 soulng::lexer::Span(), new sngcm::ast::NotEqualNode(soulng::lexer::Span(), node.release(), new sngcm::ast::SByteLiteralNode(soulng::lexer::Span(), 0))));
521 break;
522 }
523 case sngcm::ast::NodeType::byteNode:
524 {
525 node.reset(new sngcm::ast::ParenthesizedExpressionNode(
526 soulng::lexer::Span(), new sngcm::ast::NotEqualNode(soulng::lexer::Span(), node.release(), new sngcm::ast::ByteLiteralNode(soulng::lexer::Span(), 0))));
527 break;
528 }
529 case sngcm::ast::NodeType::shortNode:
530 {
531 node.reset(new sngcm::ast::ParenthesizedExpressionNode(
532 soulng::lexer::Span(), new sngcm::ast::NotEqualNode(soulng::lexer::Span(), node.release(), new sngcm::ast::ShortLiteralNode(soulng::lexer::Span(), 0))));
533 break;
534 }
535 case sngcm::ast::NodeType::ushortNode:
536 {
537 node.reset(new sngcm::ast::ParenthesizedExpressionNode(
538 soulng::lexer::Span(), new sngcm::ast::NotEqualNode(soulng::lexer::Span(), node.release(), new sngcm::ast::UShortLiteralNode(soulng::lexer::Span(), 0))));
539 break;
540 }
541 case sngcm::ast::NodeType::intNode:
542 {
543 node.reset(new sngcm::ast::ParenthesizedExpressionNode(
544 soulng::lexer::Span(), new sngcm::ast::NotEqualNode(soulng::lexer::Span(), node.release(), new sngcm::ast::IntLiteralNode(soulng::lexer::Span(), 0))));
545 break;
546 }
547 case sngcm::ast::NodeType::uintNode:
548 {
549 node.reset(new sngcm::ast::ParenthesizedExpressionNode(
550 soulng::lexer::Span(), new sngcm::ast::NotEqualNode(soulng::lexer::Span(), node.release(), new sngcm::ast::UIntLiteralNode(soulng::lexer::Span(), 0))));
551 break;
552 }
553 case sngcm::ast::NodeType::longNode:
554 {
555 node.reset(new sngcm::ast::ParenthesizedExpressionNode(
556 soulng::lexer::Span(), new sngcm::ast::NotEqualNode(soulng::lexer::Span(), node.release(), new sngcm::ast::LongLiteralNode(soulng::lexer::Span(), 0))));
557 break;
558 }
559 case sngcm::ast::NodeType::ulongNode:
560 {
561 node.reset(new sngcm::ast::ParenthesizedExpressionNode(
562 soulng::lexer::Span(), new sngcm::ast::NotEqualNode(soulng::lexer::Span(), node.release(), new sngcm::ast::ULongLiteralNode(soulng::lexer::Span(), 0))));
563 break;
564 }
565 case sngcm::ast::NodeType::floatNode:
566 {
567 node.reset(new sngcm::ast::ParenthesizedExpressionNode(
568 soulng::lexer::Span(), new sngcm::ast::NotEqualNode(soulng::lexer::Span(), node.release(), new sngcm::ast::FloatLiteralNode(soulng::lexer::Span(), 0))));
569 break;
570 }
571 case sngcm::ast::NodeType::doubleNode:
572 {
573 node.reset(new sngcm::ast::ParenthesizedExpressionNode(
574 soulng::lexer::Span(), new sngcm::ast::NotEqualNode(soulng::lexer::Span(), node.release(), new sngcm::ast::DoubleLiteralNode(soulng::lexer::Span(), 0))));
575 break;
576 }
577 case sngcm::ast::NodeType::charNode:
578 {
579 node.reset(new sngcm::ast::ParenthesizedExpressionNode(
580 soulng::lexer::Span(), new sngcm::ast::NotEqualNode(soulng::lexer::Span(), node.release(), new sngcm::ast::CharLiteralNode(soulng::lexer::Span(), '\0'))));
581 break;
582 }
583 case sngcm::ast::NodeType::wcharNode:
584 {
585 node.reset(new sngcm::ast::ParenthesizedExpressionNode(
586 soulng::lexer::Span(), new sngcm::ast::NotEqualNode(soulng::lexer::Span(), node.release(), new sngcm::ast::WCharLiteralNode(soulng::lexer::Span(), '\0'))));
587 break;
588 }
589 case sngcm::ast::NodeType::ucharNode:
590 {
591 node.reset(new sngcm::ast::ParenthesizedExpressionNode(
592 soulng::lexer::Span(), new sngcm::ast::NotEqualNode(soulng::lexer::Span(), node.release(), new sngcm::ast::UCharLiteralNode(soulng::lexer::Span(), '\0'))));
593 break;
594 }
595 }
596 }
597 }
598
599 sngcm::ast::sngcm::ast::NodeList<sngcm::ast::Node>Converter::ConvertExpressionList(sngcpp::ast::Node*expressions)
600 {
601 if (expressions)
602 {
603 bool prevAddToNodes = addToNodes;
604 addToNodes = true;
605 sngcm::ast::NodeList<sngcm::ast::Node> prevNodes = std::move(nodes);
606 if (expressions->GetNodeType() == sngcpp::ast::NodeType::expressionSequenceNode ||
607 expressions->GetNodeType() == sngcpp::ast::NodeType::memberInitializerSequenceNode ||
608 expressions->GetNodeType() == sngcpp::ast::NodeType::expressionListInitializerNode)
609 {
610 expressions->Accept(*this);
611 }
612 else
613 {
614 ConvertExpression(expressions);
615 }
616 sngcm::ast::NodeList<sngcm::ast::Node> convertedNodes = std::move(nodes);
617 nodes = std::move(prevNodes);
618 addToNodes = prevAddToNodes;
619 return convertedNodes;
620 }
621 else
622 {
623 return sngcm::ast::NodeList<sngcm::ast::Node>();
624 }
625 }
626
627 void Converter::ConvertTypeExpression(sngcpp::ast::Node* typeExprNode)
628 {
629 mappedSymbolSequence.clear();
630 node.reset();
631 typeExprNode->Accept(*this);
632 if (!node)
633 {
634 if (!mappedSymbolSequence.empty())
635 {
636 sngcpp::symbols::Symbol* symbol = mappedSymbolSequence.back();
637 if (symbol)
638 {
639 if (symbol->IsClassGroupSymbol())
640 {
641 sngcpp::symbols::ClassGroupSymbol* classGroup = static_cast<sngcpp::symbols::ClassGroupSymbol*>(symbol);
642 if (currentClassType && classGroup->Name() == currentClassType->Name())
643 {
644 symbol = currentClassType;
645 }
646 else
647 {
648 symbol = classGroup->GetClass(0);
649 }
650 }
651 if (symbol && symbol->IsTypeSymbol())
652 {
653 sngcpp::symbols::TypeSymbol* typeSymbol = static_cast<sngcpp::symbols::TypeSymbol*>(symbol);
654 sngxml::dom::Document* sourceXmlDoc = nullptr;
655 sngcm::ast::Node* typeNode = map.MapType(typeSymbol, sourceXmlDoc);
656 if (typeNode)
657 {
658 node.reset(typeNode);
659 type = typeSymbol;
660 }
661 }
662 }
663 }
664 }
665 if (!node)
666 {
667 NotConverted(typeExprNode->GetSpan().line, "type not mapped");
668 }
669 }
670
671 sngcpp::symbols::TypeSymbol* Converter::MakeCommonType(sngcpp::symbols::TypeSymbol* leftType, sngcpp::symbols::TypeSymbol* rightType)
672 {
673 if (leftType == nullptr)
674 {
675 return rightType;
676 }
677 if (rightType == nullptr)
678 {
679 return leftType;
680 }
681 if (leftType == rightType)
682 {
683 return leftType;
684 }
685 if (leftType->IsSimpleTypeSymbol() && rightType->IsSimpleTypeSymbol())
686 {
687 sngcpp::symbols::SimpleTypeSymbol* leftSimpleType = static_cast<sngcpp::symbols::SimpleTypeSymbol*>(leftType);
688 sngcpp::symbols::SimpleTypeSymbol* rightSimpleType = static_cast<sngcpp::symbols::SimpleTypeSymbol*>(rightType);
689 sngcm::ast::NodeType leftNodeType = map.MapSimpleType(leftSimpleType);
690 sngcm::ast::NodeType rightNodeType = map.MapSimpleType(rightSimpleType);
691 sngcm::ast::NodeType commonNodeType = commonType[static_cast<int>(leftNodeType)][static_cast<int>(rightNodeType)];
692 std::vector<sngcpp::symbols::SimpleTypeSpecifier> specifiers = GetSimpleTypeSpecifiers(commonNodeType);
693 sngcpp::ast::SimpleTypeNode simpleTypeNode(soulng::lexer::Span(), specifiers);
694 return symbolTable.MakeSimpleTypeSymbol(simpleTypeNode);
695 }
696 return leftType;
697 }
698
699 sngcpp::symbols::TypeSymbol* Converter::AddPointer(sngcpp::symbols::TypeSymbol* pointeeType)
700 {
701 if (!pointeeType) return nullptr;
702 std::vector<sngcpp::symbols::Derivation> derivations;
703 if (pointeeType->IsDerivedTypeSymbol())
704 {
705 sngcpp::symbols::DerivedTypeSymbol* derivedType = static_cast<sngcpp::symbols::DerivedTypeSymbol*>(pointeeType);
706 derivations = derivedType->Derivations();
707 }
708 derivations.push_back(sngcpp::symbols::Derivation::ptr);
709 return symbolTable.MakeDerivedTypeSymbol(derivations, pointeeType->BaseType());
710 }
711
712 sngcpp::symbols::TypeSymbol* Converter::RemovePointer(sngcpp::symbols::TypeSymbol* ptrType)
713 {
714 if (!ptrType) return nullptr;
715 if (ptrType->IsDerivedTypeSymbol())
716 {
717 sngcpp::symbols::DerivedTypeSymbol* derivedType = static_cast<sngcpp::symbols::DerivedTypeSymbol*>(ptrType);
718 std::vector<sngcpp::symbols::Derivation> derivations = derivedType->Derivations();
719 int n = derivations.size();
720 for (int i = n - 1; i >= 0; --i)
721 {
722 if (derivations[i] == sngcpp::symbols::Derivation::ptr)
723 {
724 derivations.erase(derivations.begin() + i);
725 if (derivations.empty())
726 {
727 return ptrType->BaseType();
728 }
729 else
730 {
731 return symbolTable.MakeDerivedTypeSymbol(derivations, ptrType->BaseType());
732 }
733 }
734 }
735 }
736 return ptrType;
737 }
738
739 sngcpp::symbols::TypeSymbol* Converter::MakeElementType(sngcpp::symbols::TypeSymbol* arrayType)
740 {
741
742 return nullptr;
743 }
744
745 void Converter::Visit(sngcpp::ast::BaseClassSpecifierNode& baseClassSpecifierNode)
746 {
747 ConvertTypeExpression(baseClassSpecifierNode.ClassName());
748 }
749
750 void Converter::Visit(sngcpp::ast::BaseClassSpecifierSequenceNode& baseClassSpecifierSequenceNode)
751 {
752 baseClassSpecifierSequenceNode.Left()->Accept(*this);
753 baseClassSpecifierSequenceNode.Right()->Accept(*this);
754 }
755
756 void Converter::Visit(sngcpp::ast::ForwardClassDeclarationNode& forwardClassDeclarationNode)
757 {
758 }
759
760 void Converter::Visit(sngcpp::ast::ElaborateClassNameNode& elaborateClassNameNode)
761 {
762 elaborateClassNameNode.ClassName()->Accept(*this);
763 }
764
765 void Converter::Visit(sngcpp::ast::ClassNode& classNode)
766 {
767 sngcpp::symbols::ClassTypeSymbol* prevClassTypeSymbol = currentClassType;
768 sngcpp::symbols::ClassTypeSymbol* prevContextClassTypeSymbol = currentContext->currentClassTypeSymbol;
769 sngcm::ast::Node* prevContainer = currentContainerNode;
770 sngcm::ast::Node* classContainer = prevContainer;
771 sngcpp::symbols::Symbol* symbol = symbolTable.GetSymbolNothrow(&classNode);
772 if (symbol)
773 {
774 if (symbol->IsClassTypeSymbol())
775 {
776 sngcpp::symbols::ClassTypeSymbol* classTypeSymbol = static_cast<sngcpp::symbols::ClassTypeSymbol*>(symbol);
777 nothrowClassItem = Item(Item::Type::class_, classTypeSymbol->Name(), nothrowFileItem.include);
778 nothrowList.ApplyTo(nothrowClassItem);
779 if (nothrowList.Verbose())
780 {
781 if (nothrowClassItem.include)
782 {
783 std::cout << "info: " << ToUtf8(classTypeSymbol->Name()) << ": nothrow=true" << std::endl;
784 }
785 else
786 {
787 std::cout << "info: " << ToUtf8(classTypeSymbol->Name()) << ": nothrow=false" << std::endl;
788 }
789 }
790 if (excludedClasses.find(classTypeSymbol->FullName()) != excludedClasses.cend())
791 {
792 if (verbose)
793 {
794 std::cout << "info: class " << ToUtf8(classTypeSymbol->FullName()) << " excluded" << std::endl;
795 }
796 }
797 else
798 {
799 currentClassType = classTypeSymbol;
800 currentContext->currentClassTypeSymbol = classTypeSymbol;
801 auto it = currentContext->containerMap.find(classTypeSymbol->Parent());
802 if (it != currentContext->containerMap.cend())
803 {
804 classContainer = it->second;
805 currentContext->currentContainerNode = classContainer;
806 }
807 cls.reset(new sngcm::ast::ClassNode(soulng::lexer::Span(), MapSpecifiers(classNode.ClassVirtSpecifiers()) | MapAccess(classTypeSymbol->Access()),
808 new sngcm::ast::IdentifierNode(soulng::lexer::Span(), classTypeSymbol->Name()), nullptr));
809 classMap[classTypeSymbol] = cls.get();
810 if (classTypeSymbol->IsAbstract())
811 {
812 cls->SetSpecifiers(cls->GetSpecifiers() | sngcm::ast::Specifiers::abstract_);
813 }
814 if (!templateParameterNodes.empty())
815 {
816 for (auto& templateParameterNode : templateParameterNodes)
817 {
818 cls->AddTemplateParameter(templateParameterNode.release());
819 }
820 }
821 currentContainerNode = cls.get();
822 currentContext->containerMap[classTypeSymbol] = currentContainerNode;
823 for (const auto& baseClass : classTypeSymbol->BaseClasses())
824 {
825 if (baseClass->IsClassTypeSymbol())
826 {
827 if (cls->BaseClassOrInterfaces().Count() == 0)
828 {
829 sngcpp::symbols::ClassTypeSymbol* baseClassType = static_cast<sngcpp::symbols::ClassTypeSymbol*>(baseClass);
830 sngxml::dom::Document* sourceXmlDoc = nullptr;
831 std::unique_ptr<sngcm::ast::Node> typeNode;
832 typeNode.reset(map.MapType(baseClassType, sourceXmlDoc));
833 if (!typeNode)
834 {
835 NotConverted(classNode.GetSpan().line, "base class not converted");
836 typeNode.reset(node.release());
837 }
838 cls->AddBaseClassOrInterface(typeNode.release());
839 }
840 else
841 {
842 NotConverted(classNode.GetSpan().line, "base class not converted");
843 }
844 }
845 else
846 {
847 NotConverted(classNode.GetSpan().line, "base class not converted");
848 }
849 }
850 classNode.Declarations()->Accept(*this);
851 currentContainerNode = classContainer;
852 AddToContainer(classNode.GetSpan().line, cls.release());
853 }
854 currentContainerNode = prevContainer;
855 }
856 else
857 {
858 currentContainerNode = prevContainer;
859 NotConverted(classNode.GetSpan().line, "class not converted");
860 }
861 }
862 else
863 {
864 currentContainerNode = prevContainer;
865 NotConverted(classNode.GetSpan().line, "class not converted");
866 }
867 currentClassType = prevClassTypeSymbol;
868 currentContext->currentClassTypeSymbol = prevContextClassTypeSymbol;
869 }
870
871 void Converter::Visit(sngcpp::ast::MemberAccessDeclarationNode& memberAccessDeclarationNode)
872 {
873 memberAccessDeclarationNode.Declaration()->Accept(*this);
874 }
875
876 void Converter::Visit(sngcpp::ast::MemberDeclarationNode& memberDeclarationNode)
877 {
878 sngcpp::symbols::Symbol* symbol = symbolTable.GetSymbolNothrow(&memberDeclarationNode);
879 if (symbol)
880 {
881 if (symbol->IsVariableSymbol())
882 {
883 sngcpp::symbols::VariableSymbol* variableSymbol = static_cast<sngcpp::symbols::VariableSymbol*>(symbol);
884 sngcpp::symbols::TypeSymbol* typeSymbol = variableSymbol->GetType();
885 sngxml::dom::Document* sourceXmlDoc = nullptr;
886 std::unique_ptr<sngcm::ast::Node> typeNode(map.MapType(typeSymbol, sourceXmlDoc));
887 if (!typeNode)
888 {
889 NotConverted(memberDeclarationNode.GetSpan().line, "type not converted");
890 typeNode.reset(node.release());
891 }
892 if (variableSymbol->Parent()->IsClassTypeSymbol())
893 {
894 node.reset(new sngcm::ast::MemberVariableNode(soulng::lexer::Span(), MapSpecifiers(variableSymbol->Specifiers()) | MapAccess(variableSymbol->Access()), typeNode.release(),
895 new sngcm::ast::IdentifierNode(soulng::lexer::Span(), variableSymbol->Name()), nullptr));
896 }
897 else
898 {
899 node.reset(new sngcm::ast::GlobalVariableNode(soulng::lexer::Span(), MapSpecifiers(variableSymbol->Specifiers()) | MapAccess(variableSymbol->Access()), typeNode.release(),
900 new sngcm::ast::IdentifierNode(soulng::lexer::Span(), variableSymbol->Name()), currentCompileUnit));
901 }
902 }
903 sngcm::ast::Node* prevContainer = currentContainerNode;
904 sngcm::ast::Node* variableContainer = currentContainerNode;
905 auto it = currentContext->containerMap.find(symbol->Parent());
906 if (it != currentContext->containerMap.cend())
907 {
908 variableContainer = it->second;
909 currentContainerNode = variableContainer;
910 }
911 currentContainerNode = variableContainer;
912 AddToContainer(memberDeclarationNode.GetSpan().line, node.release());
913 currentContainerNode = prevContainer;
914 }
915 else
916 {
917 mappedSymbolSequence.clear();
918 memberDeclarationNode.Declarator()->Accept(*this);
919 if (!mappedSymbolSequence.empty())
920 {
921 sngcpp::symbols::Symbol* symbol = mappedSymbolSequence.back();
922 if (symbol->IsFunctionSymbol())
923 {
924 sngcpp::symbols::FunctionSymbol* functionSymbol = static_cast<sngcpp::symbols::FunctionSymbol*>(symbol);
925 if ((functionSymbol->Specifiers() & sngcpp::symbols::Specifier::pure_) != sngcpp::symbols::Specifier::none)
926 {
927 sngcpp::symbols::TypeSymbol* returnTypeSymbol = functionSymbol->ReturnType();
928 sngxml::dom::Document* sourceXmlDoc = nullptr;
929 std::unique_ptr<sngcm::ast::Node> returnTypeNode(map.MapType(returnTypeSymbol, sourceXmlDoc));
930 if (!returnTypeNode)
931 {
932 NotConverted(memberDeclarationNode.GetSpan().line, "type not converted");
933 returnTypeNode.reset(node.release());
934 }
935 sngcm::ast::Specifiers functionSpecifiers = MapSpecifiers(functionSymbol->Specifiers());
936 functionSpecifiers = functionSpecifiers | MapAccess(functionSymbol->Access());
937 sngcm::ast::MemberFunctionNode* memberFunctionNode = new sngcm::ast::MemberFunctionNode(soulng::lexer::Span(), functionSpecifiers, returnTypeNode.release(),
938 functionSymbol->GroupName(), nullptr);
939 for (auto& parameterNode : parameterNodes)
940 {
941 memberFunctionNode->AddParameter(parameterNode.release());
942 }
943 AddToContainer(memberDeclarationNode.GetSpan().line, memberFunctionNode);
944 }
945 }
946 }
947 }
948 }
949
950 void Converter::Visit(sngcpp::ast::SpecialMemberFunctionNode& specialMemberFunctionNode)
951 {
952 Item prevClassItem = nothrowClassItem;
953 sngcpp::symbols::ClassTypeSymbol* prevClassType = currentClassType;
954 sngcm::ast::Node* prevContainer = currentContainerNode;
955 sngcm::ast::Node* memberFunctionContainer = prevContainer;
956 sngcm::ast::Specifiers memberFunctionSpecifiers = MapSpecifiers(specialMemberFunctionNode.Specifiers());
957 sngcpp::symbols::Symbol* symbol = symbolTable.GetSymbolNothrow(&specialMemberFunctionNode);
958 mappedSymbolSequence.clear();
959 specialMemberFunctionNode.Declarator()->Accept(*this);
960 if (mappedSymbolSequence.empty())
961 {
962 WriteWarning(specialMemberFunctionNode.GetSpan().line, "constructor/destructor name not mapped");
963 }
964 if (!symbol)
965 {
966 symbol = mappedSymbolSequence.back();
967 }
968 if (symbol)
969 {
970 bool found = false;
971 if (symbol->Parent()->IsClassTypeSymbol())
972 {
973 sngcpp::symbols::ClassTypeSymbol* cls = static_cast<sngcpp::symbols::ClassTypeSymbol*>(symbol->Parent());
974 nothrowClassItem = Item(Item::Type::class_, cls->Name(), nothrowFileItem.include);
975 nothrowList.ApplyTo(nothrowClassItem);
976 if (nothrowList.Verbose())
977 {
978 if (nothrowClassItem.include)
979 {
980 std::cout << "info: " << ToUtf8(cls->Name()) << ": nothrow=true" << std::endl;
981 }
982 else
983 {
984 std::cout << "info: " << ToUtf8(cls->Name()) << ": nothrow=false" << std::endl;
985 }
986 }
987 nothrowFunctionItem = Item(Item::Type::function, symbol->Name(), nothrowClassItem.include);
988 auto cit = classMap.find(cls);
989 if (cit != classMap.end())
990 {
991 memberFunctionContainer = cit->second;
992 currentContainerNode = memberFunctionContainer;
993 found = true;
994 }
995 }
996 if (!found)
997 {
998 nothrowFunctionItem = Item(Item::Type::function, symbol->Name(), false);
999 auto it = currentContext->containerMap.find(symbol->Parent());
1000 if (it != currentContext->containerMap.cend())
1001 {
1002 memberFunctionContainer = it->second;
1003 currentContainerNode = memberFunctionContainer;
1004 }
1005 }
1006 if (symbol->IsConstructorSymbol())
1007 {
1008 sngcpp::symbols::ConstructorSymbol* constructorSymbol = static_cast<sngcpp::symbols::ConstructorSymbol*>(symbol);
1009 memberFunctionSpecifiers = memberFunctionSpecifiers | MapSpecifiers(constructorSymbol->Specifiers()) | MapAccess(symbol->Access());
1010 nothrowList.ApplyTo(nothrowFunctionItem);
1011 if (nothrowFunctionItem.include)
1012 {
1013 memberFunctionSpecifiers = memberFunctionSpecifiers | sngcm::ast::Specifiers::nothrow_;
1014 }
1015 node.reset(new sngcm::ast::ConstructorNode(soulng::lexer::Span(), memberFunctionSpecifiers, nullptr));
1016 }
1017 else if (symbol->IsDestructorSymbol())
1018 {
1019 sngcpp::symbols::DestructorSymbol* destructorSymbol = static_cast<sngcpp::symbols::DestructorSymbol*>(symbol);
1020 memberFunctionSpecifiers = memberFunctionSpecifiers | MapSpecifiers(destructorSymbol->Specifiers()) | MapAccess(symbol->Access());
1021 nothrowList.ApplyTo(nothrowFunctionItem);
1022 node.reset(new sngcm::ast::DestructorNode(soulng::lexer::Span(), memberFunctionSpecifiers, nullptr));
1023 }
1024 else
1025 {
1026 currentContainerNode = prevContainer;
1027 currentClassType = prevClassType;
1028 WriteWarning(specialMemberFunctionNode.GetSpan().line, "constructor/destructor not created");
1029 return;
1030 }
1031 if (nothrowList.Verbose())
1032 {
1033 if (nothrowFunctionItem.include)
1034 {
1035 std::cout << "info: " << ToUtf8(symbol->Name()) << ": nothrow=true" << std::endl;
1036 }
1037 else
1038 {
1039 std::cout << "info: " << ToUtf8(symbol->Name()) << ": nothrow=false" << std::endl;
1040 }
1041 }
1042 std::unique_ptr<sngcm::ast::FunctionNode> functionNode(static_cast<sngcm::ast::FunctionNode*>(node.release()));
1043 sngcm::ast::ConstructorNode* constructorNode = nullptr;
1044 if (symbol->IsConstructorSymbol())
1045 {
1046 constructorNode = static_cast<sngcm::ast::ConstructorNode*>(functionNode.get());
1047 constructorNode->SetClassId(new sngcm::ast::IdentifierNode(soulng::lexer::Span(), symbol->Parent()->Name()));
1048 for (auto& parameterNode : parameterNodes)
1049 {
1050 constructorNode->AddParameter(parameterNode.release());
1051 }
1052 }
1053 else if (symbol->IsDestructorSymbol())
1054 {
1055 sngcm::ast::DestructorNode* destructorNode = static_cast<sngcm::ast::DestructorNode*>(functionNode.get());
1056 destructorNode->SetClassId(new sngcm::ast::IdentifierNode(soulng::lexer::Span(), symbol->Parent()->Name()));
1057 }
1058 if (!currentClassType && symbol->Parent()->IsClassTypeSymbol())
1059 {
1060 currentClassType = static_cast<sngcpp::symbols::ClassTypeSymbol*>(symbol->Parent());
1061 }
1062 if (specialMemberFunctionNode.CtorInitializer() && constructorNode)
1063 {
1064 specialMemberFunctionNode.CtorInitializer()->Accept(*this);
1065 int n = nodes.Count();
1066 for (int i = 0; i < n; ++i)
1067 {
1068 constructorNode->AddInitializer(static_cast<sngcm::ast::InitializerNode*>(nodes.Release(i)));
1069 }
1070 }
1071 if (specialMemberFunctionNode.FunctionBody())
1072 {
1073 statementNodes.clear();
1074 bool prevFunctionBody = inFunctionBody;
1075 inFunctionBody = true;
1076 specialMemberFunctionNode.FunctionBody()->Accept(*this);
1077 inFunctionBody = prevFunctionBody;
1078 if (statementNodes.size() == 1)
1079 {
1080 functionNode->SetBody(static_cast<sngcm::ast::CompoundStatementNode*>(statementNodes.front().release()));
1081 }
1082 else
1083 {
1084 WriteWarning(specialMemberFunctionNode.GetSpan().line, "function body expected");
1085 }
1086 }
1087 currentContainerNode = memberFunctionContainer;
1088 AddToContainer(specialMemberFunctionNode.GetSpan().line, functionNode.release());
1089 }
1090 currentContainerNode = prevContainer;
1091 currentClassType = prevClassType;
1092 nothrowClassItem = prevClassItem;
1093 }
1094
1095 void Converter::Visit(sngcpp::ast::CtorInitializerNode& ctorInitializerNode)
1096 {
1097 sngcm::ast::NodeList<sngcm::ast::Node> initializers = ConvertExpressionList(ctorInitializerNode.Child());
1098 nodes.Clear();
1099 int n = initializers.Count();
1100 for (int i = 0; i < n; ++i)
1101 {
1102 nodes.Add(initializers.Release(i));
1103 }
1104 }
1105
1106 void Converter::Visit(sngcpp::ast::MemberInitializerNode& memberInitializerNode)
1107 {
1108 bool prevAddToNodes = addToNodes;
1109 addToNodes = false;
1110 ConvertIdExpr(memberInitializerNode.Id());
1111 std::unique_ptr<sngcm::ast::Node> inode = std::move(node);
1112 sngcm::ast::NodeList<sngcm::ast::Node> args = ConvertExpressionList(memberInitializerNode.Initializer());
1113 sngcm::ast::InitializerNode* initializer = nullptr;
1114 if (inode->GetNodeType() == sngcm::ast::NodeType::baseNode)
1115 {
1116 initializer = new sngcm::ast::BaseInitializerNode(soulng::lexer::Span());
1117 }
1118 else if (inode->GetNodeType() == sngcm::ast::NodeType::identifierNode)
1119 {
1120 initializer = new sngcm::ast::MemberInitializerNode(soulng::lexer::Span(), static_cast<sngcm::ast::IdentifierNode*>(inode.release()));
1121 }
1122 if (initializer)
1123 {
1124 int n = args.Count();
1125 for (int i = 0; i < n; ++i)
1126 {
1127 initializer->AddArgument(args.Release(i));
1128 }
1129 }
1130 node.reset(initializer);
1131 addToNodes = prevAddToNodes;
1132 }
1133
1134 void Converter::Visit(sngcpp::ast::MemberInitializerSequenceNode& memberInitializerSequenceNode)
1135 {
1136 ConvertExpression(memberInitializerSequenceNode.Left());
1137 ConvertExpression(memberInitializerSequenceNode.Right());
1138 }
1139
1140 void Converter::Visit(sngcpp::ast::SourceFileNode& sourceFileNode)
1141 {
1142 std::string sourceFileName = Path::GetFileNameWithoutExtension(sourceFileNode.SourceFilePath());
1143 currentSourceFileName = Path::GetFileName(sourceFileNode.SourceFilePath());
1144 nothrowFileItem = Item(Item::Type::file, ToUtf32(currentSourceFileName), false);
1145 nothrowList.ApplyTo(nothrowFileItem);
1146 if (nothrowList.Verbose())
1147 {
1148 if (nothrowFileItem.include)
1149 {
1150 std::cout << "info: " << currentSourceFileName << ": nothrow=true" << std::endl;
1151 }
1152 else
1153 {
1154 std::cout << "info: " << currentSourceFileName << ": nothrow=false" << std::endl;
1155 }
1156 }
1157 sourceFileName.append(".cm");
1158 auto it = compileUnitMap.find(sourceFileName);
1159 if (it == compileUnitMap.cend())
1160 {
1161 std::string sourceFilePath = GetFullPath(Path::Combine(targetDir, sourceFileName));
1162 currentCompileUnit = new sngcm::ast::CompileUnitNode(Span(), sourceFilePath);
1163 std::string comment = "this file has been semiautomatically generated from '" + sourceFileNode.SourceFilePath() + "' using cpp2cm version " + Cpp2CmVersion();
1164 currentCompileUnit->GlobalNs()->Members().Insert(0, new sngcm::ast::CommentNode(soulng::lexer::Span(), ToUtf32(comment)));
1165 currentContext = &contextMap[currentCompileUnit];
1166 map.SetCurrentContext(currentContext);
1167 compileUnits.push_back(std::unique_ptr<sngcm::ast::CompileUnitNode>(currentCompileUnit));
1168 compileUnitMap[sourceFileName] = currentCompileUnit;
1169 }
1170 else
1171 {
1172 currentCompileUnit = it->second;
1173 std::string comment = "this file has been semiautomatically generated from '" + sourceFileNode.SourceFilePath() + "' using cpp2cm version " + Cpp2CmVersion();
1174 currentCompileUnit->GlobalNs()->Members().Insert(1, new sngcm::ast::CommentNode(soulng::lexer::Span(), ToUtf32(comment)));
1175 currentContext = &contextMap[currentCompileUnit];
1176 map.SetCurrentContext(currentContext);
1177 }
1178 map.ClearNamespaceImports();
1179 sourceFileNode.GlobalNs()->Accept(*this);
1180 for (const auto& namespaceImport : map.NamespaceImports())
1181 {
1182 currentContext->namespaceImports.insert(namespaceImport);
1183 }
1184 }
1185
1186 void Converter::Visit(sngcpp::ast::SourceFileSequenceNode& sourceFileSequenceNode)
1187 {
1188 sourceFileSequenceNode.Left()->Accept(*this);
1189 sourceFileSequenceNode.Right()->Accept(*this);
1190 }
1191
1192 void Converter::Visit(sngcpp::ast::SimpleDeclarationNode& simpleDeclarationNode)
1193 {
1194 if (simpleDeclarationNode.Declarator()->IsFunctionDeclaratorNode()) return;
1195 bool converted = false;
1196 bool prevAssignment = assignment;
1197 bool prevEmpty = empty;
1198 assignment = false;
1199 empty = false;
1200 if (!inFunctionBody)
1201 {
1202 sngcpp::symbols::Symbol* symbol = symbolTable.GetSymbolNothrow(&simpleDeclarationNode);
1203 if (symbol && symbol->IsVariableSymbol())
1204 {
1205 sngcpp::symbols::VariableSymbol* variableSymbol = static_cast<sngcpp::symbols::VariableSymbol*>(symbol);
1206 sngcpp::symbols::TypeSymbol* type = variableSymbol->GetType();
1207 if (type->IsDerivedTypeSymbol() && type->BaseType()->IsSimpleTypeSymbol())
1208 {
1209 sngcpp::symbols::DerivedTypeSymbol* derivedType = static_cast<sngcpp::symbols::DerivedTypeSymbol*>(type);
1210 if (derivedType->Derivations().size() == 2 &&
1211 derivedType->Derivations().front() == sngcpp::symbols::Derivation::const_ &&
1212 derivedType->Derivations().back() == sngcpp::symbols::Derivation::base)
1213 {
1214 std::unique_ptr<sngcm::ast::Node> typeNode;
1215 sngxml::dom::Document* sourceXmlDoc = nullptr;
1216 typeNode.reset(map.MapType(type->BaseType(), sourceXmlDoc));
1217 if (typeNode)
1218 {
1219 std::unique_ptr<sngcm::ast::Node> valueNode;
1220 simpleDeclarationNode.Declarator()->Accept(*this);
1221 if (assignment)
1222 {
1223 valueNode.reset(initializer.release());
1224 }
1225 if (valueNode)
1226 {
1227 node.reset(new sngcm::ast::ConstantNode(soulng::lexer::Span(), MapSpecifiers(simpleDeclarationNode.Specifiers()) | MapAccess(variableSymbol->Access()),
1228 typeNode.release(), new sngcm::ast::IdentifierNode(soulng::lexer::Span(), variableSymbol->Name()),
1229 valueNode.release()));
1230 AddToContainer(simpleDeclarationNode.GetSpan().line, node.release());
1231 converted = true;
1232 }
1233 }
1234 }
1235 }
1236 }
1237 }
1238 if (!converted)
1239 {
1240 ConvertTypeExpression(simpleDeclarationNode.TypeExpr());
1241 std::unique_ptr<sngcm::ast::Node> typeNode = std::move(node);
1242 sngcpp::symbols::TypeSymbol* typeSymbol = type;
1243 nodes.Clear();
1244 if (simpleDeclarationNode.Declarator())
1245 {
1246 simpleDeclarationNode.Declarator()->Accept(*this);
1247 }
1248 if (!declarator && !mappedSymbolSequence.empty())
1249 {
1250 sngcpp::symbols::Symbol* symbol = mappedSymbolSequence.back();
1251 if (symbol)
1252 {
1253 declarator.reset(new sngcm::ast::IdentifierNode(soulng::lexer::Span(), symbol->Name()));
1254 empty = true;
1255 }
1256 }
1257 if (catchDecl)
1258 {
1259 catchType.reset(typeNode.release());
1260 catchId.reset(static_cast<sngcm::ast::IdentifierNode*>(declarator.release()));
1261 converted = true;
1262 }
1263 if (typeNode && declarator && declarator->GetNodeType() == sngcm::ast::NodeType::identifierNode)
1264 {
1265 if (inFunctionBody)
1266 {
1267 if (rangeFor)
1268 {
1269 rangeForType.reset(typeNode.release());
1270 rangeForId.reset(static_cast<sngcm::ast::IdentifierNode*>(declarator.release()));
1271 converted = true;
1272 }
1273 else
1274 {
1275 sngcm::ast::ConstructionStatementNode* constructionStatement = new sngcm::ast::ConstructionStatementNode(soulng::lexer::Span(), typeNode.release(),
1276 static_cast<sngcm::ast::IdentifierNode*>(declarator.release()));
1277 if (assignment)
1278 {
1279 if (initializer)
1280 {
1281 constructionStatement->AddArgument(initializer.release());
1282 constructionStatement->SetAssignment();
1283 }
1284 else
1285 {
1286 WriteWarning(simpleDeclarationNode.GetSpan().line, "assignment flag set for simple declaration with no initializer");
1287 }
1288 }
1289 else
1290 {
1291 int n = nodes.Count();
1292 for (int i = 0; i < n; ++i)
1293 {
1294 constructionStatement->AddArgument(nodes.Release(i));
1295 }
1296 if (empty)
1297 {
1298 if (n == 0)
1299 {
1300 constructionStatement->SetEmpty();
1301 }
1302 else
1303 {
1304 WriteWarning(simpleDeclarationNode.GetSpan().line, "empty flag set for simple declaration conflicts with number of arguments (" + std::to_string(n) + ")");
1305 }
1306 }
1307 }
1308 AddStatement(simpleDeclarationNode.GetSpan().line, constructionStatement);
1309 converted = true;
1310 }
1311 }
1312 }
1313 else if (!converted && inFunctionBody && typeNode)
1314 {
1315 sngcm::ast::ConstructionStatementNode* constructionStatement = new sngcm::ast::ConstructionStatementNode(soulng::lexer::Span(), typeNode.release(),
1316 new sngcm::ast::IdentifierNode(soulng::lexer::Span(), U"NOT_CONVERTED"));
1317 AddStatement(simpleDeclarationNode.GetSpan().line, constructionStatement);
1318 converted = true;
1319 }
1320 }
1321 if (!converted)
1322 {
1323 NotConverted(simpleDeclarationNode.GetSpan().line, "simple declaration not converted");
1324 }
1325 assignment = prevAssignment;
1326 empty = prevEmpty;
1327 }
1328
1329 void Converter::Visit(sngcpp::ast::AliasDeclarationNode& aliasDeclarationNode)
1330 {
1331 NotConverted(aliasDeclarationNode.GetSpan().line, "alias declaration not converted");
1332 }
1333
1334 void Converter::Visit(sngcpp::ast::UsingDirectiveNode& usingDirectiveNode)
1335 {
1336 NotConverted(usingDirectiveNode.GetSpan().line, "using directive not converted");
1337 }
1338
1339 void Converter::Visit(sngcpp::ast::UsingDeclarationNode& usingDeclarationNode)
1340 {
1341 NotConverted(usingDeclarationNode.GetSpan().line, "using declaration not converted");
1342 }
1343
1344 void Converter::Visit(sngcpp::ast::TypedefNode& typedefNode)
1345 {
1346 NotConverted(typedefNode.GetSpan().line, "typedef not converted");
1347 }
1348
1349 void Converter::Visit(sngcpp::ast::DeclarationSequenceNode& declarationSequenceNode)
1350 {
1351 declarationSequenceNode.Left()->Accept(*this);
1352 declarationSequenceNode.Right()->Accept(*this);
1353 }
1354
1355 void Converter::Visit(sngcpp::ast::LinkageSpecificationNode& linkageSpecificationNode)
1356 {
1357 NotConverted(linkageSpecificationNode.GetSpan().line, "linkage specification not converted");
1358 }
1359
1360 void Converter::Visit(sngcpp::ast::IdDeclaratorNode& idDeclaratorNode)
1361 {
1362 mappedSymbolSequence.clear();
1363 idDeclaratorNode.IdNode()->Accept(*this);
1364 }
1365
1366 void Converter::Visit(sngcpp::ast::ArrayDeclaratorNode& arrayDeclaratorNode)
1367 {
1368 NotConverted(arrayDeclaratorNode.GetSpan().line, "array declarator not converted");
1369 }
1370
1371 void Converter::Visit(sngcpp::ast::FunctionDeclaratorNode& functionDeclaratorNode)
1372 {
1373 sngcpp::symbols::Symbol* symbol = symbolTable.GetSymbolNothrow(&functionDeclaratorNode);
1374 if (symbol)
1375 {
1376 if (symbol->IsCallableSymbol())
1377 {
1378 sngcpp::symbols::CallableSymbol* functionSymbol = static_cast<sngcpp::symbols::CallableSymbol*>(symbol);
1379 parameterNodes.clear();
1380 for (sngcpp::symbols::ParameterSymbol* parameterSymbol : functionSymbol->Parameters())
1381 {
1382 sngxml::dom::Document* sourceXmlDoc = nullptr;
1383 std::unique_ptr<sngcm::ast::Node> typeNode(map.MapType(parameterSymbol->GetType(), sourceXmlDoc));
1384 if (!typeNode)
1385 {
1386 NotConverted(functionDeclaratorNode.GetSpan().line, "type not converted");
1387 typeNode.reset(node.release());
1388 }
1389 sngcm::ast::IdentifierNode* idNode = new sngcm::ast::IdentifierNode(soulng::lexer::Span(), parameterSymbol->Name());
1390 std::unique_ptr<sngcm::ast::ParameterNode> paramNode(new sngcm::ast::ParameterNode(soulng::lexer::Span(), typeNode.release(), idNode));
1391 parameterNodes.push_back(std::move(paramNode));
1392 }
1393 mappedSymbolSequence.push_back(functionSymbol);
1394 return;
1395 }
1396 }
1397 functionDeclaratorNode.Declarator()->Accept(*this);
1398 parameterNodes.clear();
1399 if (functionDeclaratorNode.Parameters())
1400 {
1401 functionDeclaratorNode.Parameters()->Accept(*this);
1402 }
1403 }
1404
1405 void Converter::Visit(sngcpp::ast::FunctionPtrIdNode& functionPtrIdNode)
1406 {
1407 NotConverted(functionPtrIdNode.GetSpan().line, "function ptr id not converted");
1408
1409 int x = 0;
1410 }
1411
1412 void Converter::Visit(sngcpp::ast::MemberFunctionPtrIdNode& memberFunctionPtrIdNode)
1413 {
1414 NotConverted(memberFunctionPtrIdNode.GetSpan().line, "member function ptr id not converted");
1415
1416 int x = 0;
1417 }
1418
1419 void Converter::Visit(sngcpp::ast::InitDeclaratorNode& initDeclaratorNode)
1420 {
1421 declarator.reset();
1422 ConvertExpression(initDeclaratorNode.Declarator());
1423 declarator = std::move(node);
1424 initializer.reset();
1425 if (initDeclaratorNode.Initializer())
1426 {
1427 ConvertExpression(initDeclaratorNode.Initializer());
1428 initializer = std::move(node);
1429 }
1430 else
1431 {
1432 empty = true;
1433 }
1434 }
1435
1436 void Converter::Visit(sngcpp::ast::AssignmentInitializerNode& assignmentInitializerNode)
1437 {
1438 assignmentInitializerNode.Child()->Accept(*this);
1439 nodes.Clear();
1440 nodes.Add(node.release());
1441 assignment = true;
1442 }
1443
1444 void Converter::Visit(sngcpp::ast::ExpressionListInitializerNode& expressionListInitializerNode)
1445 {
1446 sngcm::ast::NodeList<sngcm::ast::Node> initializers = ConvertExpressionList(expressionListInitializerNode.Child());
1447 nodes.Clear();
1448 int n = initializers.Count();
1449 for (int i = 0; i < n; ++i)
1450 {
1451 nodes.Add(initializers.Release(i));
1452 }
1453 }
1454
1455 void Converter::Visit(sngcpp::ast::ExpressionInitializerNode& expressionInitializerNode)
1456 {
1457 bool prevAddToNodes = addToNodes;
1458 addToNodes = false;
1459 ConvertExpression(expressionInitializerNode.Child());
1460 addToNodes = prevAddToNodes;
1461 }
1462
1463 void Converter::Visit(sngcpp::ast::BracedInitializerListNode& bracedInitializerListNode)
1464 {
1465 sngcm::ast::NodeList<sngcm::ast::Node> initializers = ConvertExpressionList(bracedInitializerListNode.Child());
1466 nodes.Clear();
1467 int n = initializers.Count();
1468 for (int i = 0; i < n; ++i)
1469 {
1470 nodes.Add(initializers.Release(i));
1471 }
1472 }
1473
1474 void Converter::Visit(sngcpp::ast::EnumTypeNode& enumTypeNode)
1475 {
1476 sngcm::ast::EnumTypeNode* prevEnumType = currentEnumType;
1477 sngcpp::symbols::Symbol* symbol = symbolTable.GetSymbolNothrow(&enumTypeNode);
1478 if (symbol && symbol->IsEnumTypeSymbol())
1479 {
1480 sngcpp::symbols::EnumTypeSymbol* enumTypeSymbol = static_cast<sngcpp::symbols::EnumTypeSymbol*>(symbol);
1481 sngcm::ast::Specifiers enumTypeSpecifiers = sngcm::ast::Specifiers::none;
1482 std::unique_ptr<sngcm::ast::EnumTypeNode> enumeratedTypeNode(new sngcm::ast::EnumTypeNode(soulng::lexer::Span(), enumTypeSpecifiers | MapAccess(enumTypeSymbol->Access()),
1483 new sngcm::ast::IdentifierNode(soulng::lexer::Span(), enumTypeSymbol->Name())));
1484 if (enumTypeSymbol->BaseType())
1485 {
1486 sngxml::dom::Document* sourceXmlDoc = nullptr;
1487 std::unique_ptr<sngcm::ast::Node> typeNode(map.MapType(enumTypeSymbol->BaseType(), sourceXmlDoc));
1488 if (!typeNode)
1489 {
1490 NotConverted(enumTypeNode.GetSpan().line, "enum type underlying type not converted");
1491 typeNode.reset(node.release());
1492 }
1493 enumeratedTypeNode->SetUnderlyingType(typeNode.release());
1494 }
1495 currentEnumType = enumeratedTypeNode.get();
1496 enumTypeNode.Enumerators()->Accept(*this);
1497 AddToContainer(enumTypeNode.GetSpan().line, enumeratedTypeNode.release());
1498 }
1499 else
1500 {
1501 NotConverted(enumTypeNode.GetSpan().line, "enum type not converted");
1502 }
1503 currentEnumType = prevEnumType;
1504 }
1505
1506 void Converter::Visit(sngcpp::ast::EnumeratorNode& enumeratorNode)
1507 {
1508 bool hasValue = false;
1509 std::unique_ptr<sngcm::ast::Node> value;
1510 if (enumeratorNode.Value())
1511 {
1512 ConvertExpression(enumeratorNode.Value());
1513 value.reset(node.release());
1514 hasValue = true;
1515 }
1516 std::unique_ptr<sngcm::ast::EnumConstantNode> enumConstant(new sngcm::ast::EnumConstantNode(soulng::lexer::Span(), new sngcm::ast::IdentifierNode(soulng::lexer::Span(),
1517 enumeratorNode.Enumerator()), value.release()));
1518 if (hasValue)
1519 {
1520 enumConstant->SetHasValue();
1521 }
1522 currentEnumType->AddConstant(enumConstant.release());
1523 }
1524
1525 void Converter::Visit(sngcpp::ast::EnumeratorSequenceNode& enumeratorSequenceNode)
1526 {
1527 enumeratorSequenceNode.Left()->Accept(*this);
1528 enumeratorSequenceNode.Right()->Accept(*this);
1529 }
1530
1531 void Converter::Visit(sngcpp::ast::ExpressionSequenceNode& expressionSequenceNode)
1532 {
1533 ConvertExpression(expressionSequenceNode.Left());
1534 ConvertExpression(expressionSequenceNode.Right());
1535 }
1536
1537 void Converter::Visit(sngcpp::ast::CommaExpressionNode& commaExpressionNode)
1538 {
1539 NotConverted(commaExpressionNode.GetSpan().line, "comma expression not converted");
1540
1541 int x = 0;
1542 }
1543
1544 void Converter::Visit(sngcpp::ast::AssignmentExpressionNode& assignmentExpressionNode)
1545 {
1546 bool prevAddToNodes = addToNodes;
1547 addToNodes = false;
1548 ConvertExpression(assignmentExpressionNode.Left());
1549 std::unique_ptr<sngcm::ast::Node> target = std::move(node);
1550 ConvertExpression(assignmentExpressionNode.Left());
1551 std::unique_ptr<sngcm::ast::Node> left = std::move(node);
1552 ConvertExpression(assignmentExpressionNode.Right());
1553 std::unique_ptr<sngcm::ast::Node> right = std::move(node);
1554 std::unique_ptr<sngcm::ast::Node> source;
1555 switch (assignmentExpressionNode.Op())
1556 {
1557 case sngcpp::ast::Operator::assign: source.reset(right.release()); break;
1558 case sngcpp::ast::Operator::mulAssign: source.reset(new sngcm::ast::MulNode(soulng::lexer::Span(), left.release(), right.release())); break;
1559 case sngcpp::ast::Operator::divAssign: source.reset(new sngcm::ast::DivNode(soulng::lexer::Span(), left.release(), right.release())); break;
1560 case sngcpp::ast::Operator::remAssign: source.reset(new sngcm::ast::RemNode(soulng::lexer::Span(), left.release(), right.release())); break;
1561 case sngcpp::ast::Operator::addAssign: source.reset(new sngcm::ast::AddNode(soulng::lexer::Span(), left.release(), right.release())); break;
1562 case sngcpp::ast::Operator::subAssign: source.reset(new sngcm::ast::SubNode(soulng::lexer::Span(), left.release(), right.release())); break;
1563 case sngcpp::ast::Operator::shiftRightAssign: source.reset(new sngcm::ast::ShiftRightNode(soulng::lexer::Span(), left.release(), right.release())); break;
1564 case sngcpp::ast::Operator::shiftLeftAssign: source.reset(new sngcm::ast::ShiftLeftNode(soulng::lexer::Span(), left.release(), right.release())); break;
1565 case sngcpp::ast::Operator::andAssign: source.reset(new sngcm::ast::BitAndNode(soulng::lexer::Span(), left.release(), right.release())); break;
1566 case sngcpp::ast::Operator::xorAssign: source.reset(new sngcm::ast::BitXorNode(soulng::lexer::Span(), left.release(), right.release())); break;
1567 case sngcpp::ast::Operator::orAssign: source.reset(new sngcm::ast::BitOrNode(soulng::lexer::Span(), left.release(), right.release())); break;
1568 default:
1569 {
1570 NotConverted(assignmentExpressionNode.GetSpan().line, "assignment operator expected");
1571 }
1572 }
1573 sngcm::ast::AssignmentStatementNode* stmt = new sngcm::ast::AssignmentStatementNode(soulng::lexer::Span(), target.release(), source.release());
1574 AddStatement(assignmentExpressionNode.GetSpan().line, stmt);
1575 node.reset(new sngcm::ast::EmptyStatementNode(soulng::lexer::Span()));
1576 assignmentStatement = true;
1577 type = nullptr;
1578 addToNodes = prevAddToNodes;
1579 }
1580
1581 void Converter::Visit(sngcpp::ast::ConditionalExpressionNode& conditionalExpressionNode)
1582 {
1583 NotConverted(conditionalExpressionNode.GetSpan().line, "conditional expression not converted");
1584
1585 int x = 0;
1586 }
1587
1588 void Converter::Visit(sngcpp::ast::ThrowExpressionNode& throwExpressionNode)
1589 {
1590 std::unique_ptr<sngcm::ast::Node> exception;
1591 if (throwExpressionNode.Child())
1592 {
1593 ConvertExpression(throwExpressionNode.Child());
1594 exception.reset(node.release());
1595 }
1596 AddStatement(throwExpressionNode.GetSpan().line, new sngcm::ast::ThrowStatementNode(soulng::lexer::Span(), exception.release()));
1597 node.reset(new sngcm::ast::EmptyStatementNode(soulng::lexer::Span()));
1598 type = nullptr;
1599 }
1600
1601 void Converter::Visit(sngcpp::ast::LogicalOrExpressionNode& logicalOrExpressionNode)
1602 {
1603 bool prevAddToNodes = addToNodes;
1604 addToNodes = false;
1605 ConvertBooleanExpression(logicalOrExpressionNode.Left());
1606 std::unique_ptr<sngcm::ast::Node> left = std::move(node);
1607 ConvertBooleanExpression(logicalOrExpressionNode.Right());
1608 std::unique_ptr<sngcm::ast::Node> right = std::move(node);
1609 node.reset(new sngcm::ast::DisjunctionNode(soulng::lexer::Span(), left.release(), right.release()));
1610 type = symbolTable.GetBoolType();
1611 addToNodes = prevAddToNodes;
1612 }
1613
1614 void Converter::Visit(sngcpp::ast::LogicalAndExpressionNode& logicalAndExpressionNode)
1615 {
1616 bool prevAddToNodes = addToNodes;
1617 addToNodes = false;
1618 ConvertBooleanExpression(logicalAndExpressionNode.Left());
1619 std::unique_ptr<sngcm::ast::Node> left = std::move(node);
1620 ConvertBooleanExpression(logicalAndExpressionNode.Right());
1621 std::unique_ptr<sngcm::ast::Node> right = std::move(node);
1622 node.reset(new sngcm::ast::ConjunctionNode(soulng::lexer::Span(), left.release(), right.release()));
1623 type = symbolTable.GetBoolType();
1624 addToNodes = prevAddToNodes;
1625 }
1626
1627 void Converter::Visit(sngcpp::ast::InclusiveOrExpressionNode& inclusiveOrExpressionNode)
1628 {
1629 bool prevAddToNodes = addToNodes;
1630 addToNodes = false;
1631 ConvertExpression(inclusiveOrExpressionNode.Left());
1632 std::unique_ptr<sngcm::ast::Node> left = std::move(node);
1633 sngcpp::symbols::TypeSymbol* leftType = type;
1634 ConvertExpression(inclusiveOrExpressionNode.Right());
1635 std::unique_ptr<sngcm::ast::Node> right = std::move(node);
1636 sngcpp::symbols::TypeSymbol* rightType = type;
1637 node.reset(new sngcm::ast::BitOrNode(soulng::lexer::Span(), left.release(), right.release()));
1638 type = MakeCommonType(leftType, rightType);
1639 addToNodes = prevAddToNodes;
1640 }
1641
1642 void Converter::Visit(sngcpp::ast::ExclusiveOrExpressionNode& exclusiveOrExpressionNode)
1643 {
1644 bool prevAddToNodes = addToNodes;
1645 addToNodes = false;
1646 ConvertExpression(exclusiveOrExpressionNode.Left());
1647 std::unique_ptr<sngcm::ast::Node> left = std::move(node);
1648 sngcpp::symbols::TypeSymbol* leftType = type;
1649 ConvertExpression(exclusiveOrExpressionNode.Right());
1650 std::unique_ptr<sngcm::ast::Node> right = std::move(node);
1651 sngcpp::symbols::TypeSymbol* rightType = type;
1652 node.reset(new sngcm::ast::BitXorNode(soulng::lexer::Span(), left.release(), right.release()));
1653 type = MakeCommonType(leftType, rightType);
1654 addToNodes = prevAddToNodes;
1655 }
1656
1657 void Converter::Visit(sngcpp::ast::AndExpressionNode& andExpressionNode)
1658 {
1659 bool prevAddToNodes = addToNodes;
1660 addToNodes = false;
1661 ConvertExpression(andExpressionNode.Left());
1662 std::unique_ptr<sngcm::ast::Node> left = std::move(node);
1663 sngcpp::symbols::TypeSymbol* leftType = type;
1664 ConvertExpression(andExpressionNode.Right());
1665 std::unique_ptr<sngcm::ast::Node> right = std::move(node);
1666 sngcpp::symbols::TypeSymbol* rightType = type;
1667 node.reset(new sngcm::ast::BitAndNode(soulng::lexer::Span(), left.release(), right.release()));
1668 type = MakeCommonType(leftType, rightType);
1669 addToNodes = prevAddToNodes;
1670 }
1671
1672 void Converter::Visit(sngcpp::ast::EqualityExpressionNode& equalityExpressionNode)
1673 {
1674 bool prevAddToNodes = addToNodes;
1675 addToNodes = false;
1676 ConvertExpression(equalityExpressionNode.Left());
1677 std::unique_ptr<sngcm::ast::Node> left = std::move(node);
1678 ConvertExpression(equalityExpressionNode.Right());
1679 std::unique_ptr<sngcm::ast::Node> right = std::move(node);
1680 switch (equalityExpressionNode.Op())
1681 {
1682 case sngcpp::ast::Operator::equal: node.reset(new sngcm::ast::EqualNode(soulng::lexer::Span(), left.release(), right.release())); break;
1683 case sngcpp::ast::Operator::notEqual: node.reset(new sngcm::ast::NotEqualNode(soulng::lexer::Span(), left.release(), right.release())); break;
1684 default:
1685 {
1686 WriteWarning(equalityExpressionNode.GetSpan().line, "equality operator expected");
1687 node.reset();
1688 break;
1689 }
1690 }
1691 type = symbolTable.GetBoolType();
1692 addToNodes = prevAddToNodes;
1693 }
1694
1695 void Converter::Visit(sngcpp::ast::RelationalExpressionNode& relationalExpressionNode)
1696 {
1697 bool prevAddToNodes = addToNodes;
1698 addToNodes = false;
1699 ConvertExpression(relationalExpressionNode.Left());
1700 std::unique_ptr<sngcm::ast::Node> left = std::move(node);
1701 ConvertExpression(relationalExpressionNode.Right());
1702 std::unique_ptr<sngcm::ast::Node> right = std::move(node);
1703 switch (relationalExpressionNode.Op())
1704 {
1705 case sngcpp::ast::Operator::less: node.reset(new sngcm::ast::LessNode(soulng::lexer::Span(), left.release(), right.release())); break;
1706 case sngcpp::ast::Operator::greater: node.reset(new sngcm::ast::GreaterNode(soulng::lexer::Span(), left.release(), right.release())); break;
1707 case sngcpp::ast::Operator::lessOrEqual: node.reset(new sngcm::ast::LessOrEqualNode(soulng::lexer::Span(), left.release(), right.release())); break;
1708 case sngcpp::ast::Operator::greaterOrEqual: node.reset(new sngcm::ast::GreaterOrEqualNode(soulng::lexer::Span(), left.release(), right.release())); break;
1709 default:
1710 {
1711 WriteWarning(relationalExpressionNode.GetSpan().line, "relational operator expected");
1712 node.reset();
1713 break;
1714 }
1715 }
1716 type = symbolTable.GetBoolType();
1717 addToNodes = prevAddToNodes;
1718 }
1719
1720 void Converter::Visit(sngcpp::ast::ShiftExpressionNode& shiftExpressionNode)
1721 {
1722 bool prevAddToNodes = addToNodes;
1723 addToNodes = false;
1724 ConvertExpression(shiftExpressionNode.Left());
1725 std::unique_ptr<sngcm::ast::Node> left = std::move(node);
1726 sngcpp::symbols::TypeSymbol* leftType = type;
1727 ConvertExpression(shiftExpressionNode.Right());
1728 std::unique_ptr<sngcm::ast::Node> right = std::move(node);
1729 sngcpp::symbols::TypeSymbol* rightType = type;
1730 switch (shiftExpressionNode.Op())
1731 {
1732 case sngcpp::ast::Operator::shiftLeft: node.reset(new sngcm::ast::ShiftLeftNode(soulng::lexer::Span(), left.release(), right.release())); break;
1733 case sngcpp::ast::Operator::shiftRight: node.reset(new sngcm::ast::ShiftRightNode(soulng::lexer::Span(), left.release(), right.release())); break;
1734 default:
1735 {
1736 NotConverted(shiftExpressionNode.GetSpan().line, "shift operator expected");
1737 break;
1738 }
1739 }
1740 type = MakeCommonType(leftType, rightType);
1741 addToNodes = prevAddToNodes;
1742 }
1743
1744 void Converter::Visit(sngcpp::ast::AdditiveExpressionNode& additiveExpressionNode)
1745 {
1746 bool prevAddToNodes = addToNodes;
1747 addToNodes = false;
1748 ConvertExpression(additiveExpressionNode.Left());
1749 std::unique_ptr<sngcm::ast::Node> left = std::move(node);
1750 sngcpp::symbols::TypeSymbol* leftType = type;
1751 ConvertExpression(additiveExpressionNode.Right());
1752 std::unique_ptr<sngcm::ast::Node> right = std::move(node);
1753 sngcpp::symbols::TypeSymbol* rightType = type;
1754 switch (additiveExpressionNode.Op())
1755 {
1756 case sngcpp::ast::Operator::add: node.reset(new sngcm::ast::AddNode(soulng::lexer::Span(), left.release(), right.release())); break;
1757 case sngcpp::ast::Operator::sub: node.reset(new sngcm::ast::SubNode(soulng::lexer::Span(), left.release(), right.release())); break;
1758 default:
1759 {
1760 NotConverted(additiveExpressionNode.GetSpan().line, "additive operator expected");
1761 break;
1762 }
1763 }
1764 type = MakeCommonType(leftType, rightType);
1765 addToNodes = prevAddToNodes;
1766 }
1767
1768 void Converter::Visit(sngcpp::ast::MultiplicativeExpressionNode& multiplicativeExpressionNode)
1769 {
1770 bool prevAddToNodes = addToNodes;
1771 addToNodes = false;
1772 ConvertExpression(multiplicativeExpressionNode.Left());
1773 std::unique_ptr<sngcm::ast::Node> left = std::move(node);
1774 sngcpp::symbols::TypeSymbol* leftType = type;
1775 ConvertExpression(multiplicativeExpressionNode.Right());
1776 std::unique_ptr<sngcm::ast::Node> right = std::move(node);
1777 sngcpp::symbols::TypeSymbol* rightType = type;
1778 switch (multiplicativeExpressionNode.Op())
1779 {
1780 case sngcpp::ast::Operator::mul: node.reset(new sngcm::ast::MulNode(soulng::lexer::Span(), left.release(), right.release())); break;
1781 case sngcpp::ast::Operator::div: node.reset(new sngcm::ast::DivNode(soulng::lexer::Span(), left.release(), right.release())); break;
1782 case sngcpp::ast::Operator::rem: node.reset(new sngcm::ast::RemNode(soulng::lexer::Span(), left.release(), right.release())); break;
1783 default:
1784 {
1785 NotConverted(multiplicativeExpressionNode.GetSpan().line, "multiplicative operator expected");
1786 break;
1787 }
1788 }
1789 type = MakeCommonType(leftType, rightType);
1790 addToNodes = prevAddToNodes;
1791 }
1792
1793 void Converter::Visit(sngcpp::ast::PMExpressionNode& pmExpressionNode)
1794 {
1795 NotConverted(pmExpressionNode.GetSpan().line, "pointer-to-member expression not converted");
1796
1797 int x = 0;
1798 type = nullptr;
1799 }
1800
1801 void Converter::Visit(sngcpp::ast::CastExpressionNode& castExpressionNode)
1802 {
1803 bool prevAddToNodes = addToNodes;
1804 addToNodes = false;
1805 ConvertTypeExpression(castExpressionNode.TypeExpr());
1806 std::unique_ptr<sngcm::ast::Node> typeNode = std::move(node);
1807 sngcpp::symbols::TypeSymbol* targetType = type;
1808 ConvertExpression(castExpressionNode.Expr());
1809 node.reset(new sngcm::ast::CastNode(soulng::lexer::Span(), typeNode.release(), node.release()));
1810 type = targetType;
1811 addToNodes = prevAddToNodes;
1812 }
1813
1814 void Converter::Visit(sngcpp::ast::UnaryExpressionNode& unaryExpressionNode)
1815 {
1816 bool prevAddToNodes = addToNodes;
1817 addToNodes = false;
1818 if (unaryExpressionNode.Op() == sngcpp::ast::Operator::not_)
1819 {
1820 ConvertBooleanExpression(unaryExpressionNode.Child());
1821 }
1822 else
1823 {
1824 ConvertExpression(unaryExpressionNode.Child());
1825 }
1826 std::unique_ptr<sngcm::ast::Node> operand = std::move(node);
1827 switch (unaryExpressionNode.Op())
1828 {
1829 case sngcpp::ast::Operator::inc: node.reset(new sngcm::ast::PrefixIncrementNode(soulng::lexer::Span(), operand.release())); break;
1830 case sngcpp::ast::Operator::dec: node.reset(new sngcm::ast::PrefixDecrementNode(soulng::lexer::Span(), operand.release())); break;
1831 case sngcpp::ast::Operator::deref:
1832 {
1833 node.reset(new sngcm::ast::DerefNode(soulng::lexer::Span(), operand.release()));
1834 type = RemovePointer(type);
1835 break;
1836 }
1837 case sngcpp::ast::Operator::addrOf:
1838 {
1839 node.reset(new sngcm::ast::AddrOfNode(soulng::lexer::Span(), operand.release()));
1840 type = AddPointer(type);
1841 break;
1842 }
1843 case sngcpp::ast::Operator::unaryPlus: node.reset(new sngcm::ast::UnaryPlusNode(soulng::lexer::Span(), operand.release())); break;
1844 case sngcpp::ast::Operator::unaryMinus: node.reset(new sngcm::ast::UnaryMinusNode(soulng::lexer::Span(), operand.release())); break;
1845 case sngcpp::ast::Operator::not_:
1846 {
1847 node.reset(new sngcm::ast::NotNode(soulng::lexer::Span(), operand.release()));
1848 type = symbolTable.GetBoolType();
1849 break;
1850 }
1851 case sngcpp::ast::Operator::complement: node.reset(new sngcm::ast::ComplementNode(soulng::lexer::Span(), operand.release())); break;
1852 case sngcpp::ast::Operator::sizeOf:
1853 {
1854 node.reset(new sngcm::ast::SizeOfNode(soulng::lexer::Span(), operand.release()));
1855 type = symbolTable.GetLongType();
1856 break;
1857 }
1858 case sngcpp::ast::Operator::alignOf:
1859 {
1860 NotConverted(unaryExpressionNode.GetSpan().line, "align-of expression not converted");
1861 break;
1862 }
1863 default:
1864 {
1865 NotConverted(unaryExpressionNode.GetSpan().line, "unary operator expected");
1866 node.reset();
1867 type = nullptr;
1868 break;
1869 }
1870 }
1871 addToNodes = prevAddToNodes;
1872 }
1873
1874 void Converter::Visit(sngcpp::ast::NewExpressionNode& newExpressionNode)
1875 {
1876 bool prevAddToNodes = addToNodes;
1877 addToNodes = false;
1878 if (newExpressionNode.Placement())
1879 {
1880 NotConverted(newExpressionNode.GetSpan().line, "placement not converted");
1881 }
1882 ConvertTypeExpression(newExpressionNode.TypeExpr());
1883 std::unique_ptr<sngcm::ast::Node> typeNode = std::move(node);
1884 sngcpp::symbols::TypeSymbol* pointeeType = type;
1885 sngcm::ast::NodeList<sngcm::ast::Node> args;
1886 if (newExpressionNode.Initializer())
1887 {
1888 args = ConvertExpressionList(newExpressionNode.Initializer());
1889 }
1890 sngcm::ast::NewNode* newNode = new sngcm::ast::NewNode(soulng::lexer::Span(), typeNode.release());
1891 int n = args.Count();
1892 for (int i = 0; i < n; ++i)
1893 {
1894 newNode->AddArgument(args.Release(i));
1895 }
1896 node.reset(newNode);
1897 type = AddPointer(pointeeType);
1898 addToNodes = prevAddToNodes;
1899 }
1900
1901 void Converter::Visit(sngcpp::ast::DeleteExpressionNode& deleteExpressionNode)
1902 {
1903 bool prevAddToNodes = addToNodes;
1904 addToNodes = false;
1905 if (deleteExpressionNode.Array())
1906 {
1907 WriteWarning(deleteExpressionNode.GetSpan().line, "delete array not converted");
1908 deleteExpressionNode.Child()->Accept(*this);
1909 }
1910 else
1911 {
1912 ConvertExpression(deleteExpressionNode.Child());
1913 std::unique_ptr<sngcm::ast::Node> ptr = std::move(node);
1914 AddStatement(deleteExpressionNode.GetSpan().line, new sngcm::ast::DeleteStatementNode(soulng::lexer::Span(), ptr.release()));
1915 node.reset(new sngcm::ast::EmptyStatementNode(soulng::lexer::Span()));
1916 }
1917 type = nullptr;
1918 addToNodes = prevAddToNodes;
1919 }
1920
1921 void Converter::Visit(sngcpp::ast::SubscriptExpressionNode& subscriptExpressionNode)
1922 {
1923 bool prevAddToNodes = addToNodes;
1924 addToNodes = false;
1925 ConvertExpression(subscriptExpressionNode.Child());
1926 std::unique_ptr<sngcm::ast::Node> subject = std::move(node);
1927 sngcpp::symbols::TypeSymbol* subjectType = type;
1928 ConvertExpression(subscriptExpressionNode.Index());
1929 std::unique_ptr<sngcm::ast::Node> index = std::move(node);
1930 node.reset(new sngcm::ast::IndexingNode(soulng::lexer::Span(), subject.release(), index.release()));
1931 type = MakeElementType(subjectType);
1932 addToNodes = prevAddToNodes;
1933 }
1934
1935 void Converter::Visit(sngcpp::ast::InvokeExpressionNode& invokeExpressionNode)
1936 {
1937 std::u32string callArgs;
1938 std::u32string prevArgs = args;
1939 args.clear();
1940 sngcpp::symbols::CallableSymbol* prevFunctionSymbol = calledFunction;
1941 calledFunction = nullptr;
1942 sngcpp::symbols::CallableSymbol* primaryCalledFunction = nullptr;
1943 sngcpp::symbols::Symbol* symbol = symbolTable.GetSymbolNothrow(&invokeExpressionNode);
1944 if (symbol && symbol->IsCallableSymbol())
1945 {
1946 calledFunction = static_cast<sngcpp::symbols::CallableSymbol*>(symbol);
1947 primaryCalledFunction = calledFunction;
1948 }
1949 bool prevAddToNodes = addToNodes;
1950 addToNodes = false;
1951 ConvertExpression(invokeExpressionNode.Child());
1952 if (calledFunction && args.empty())
1953 {
1954 std::unique_ptr<sngcm::ast::IdentifierNode> idNode(map.MapFunctionSymbol(calledFunction, args));
1955 }
1956 calledFunction = prevFunctionSymbol;
1957 callArgs = args;
1958 std::vector<int> argIndeces;
1959 if (!callArgs.empty())
1960 {
1961 argIndeces = ParseArgs(callArgs);
1962 }
1963 args = prevArgs;
1964 std::unique_ptr<sngcm::ast::Node> subject = std::move(node);
1965 sngcpp::symbols::TypeSymbol* subjectType = type;
1966 sngcm::ast::NodeList<sngcm::ast::Node> args = ConvertExpressionList(invokeExpressionNode.Arguments());
1967 sngcm::ast::InvokeNode* invoke = new sngcm::ast::InvokeNode(soulng::lexer::Span(), subject.release());
1968 int n = args.Count();
1969 for (int i = 0; i < n; ++i)
1970 {
1971 int index = i;
1972 if (i < argIndeces.size())
1973 {
1974 index = argIndeces[i];
1975 }
1976 invoke->AddArgument(args.Release(index));
1977 }
1978 node.reset(invoke);
1979 type = nullptr;
1980 if (primaryCalledFunction)
1981 {
1982 if (primaryCalledFunction->ReturnType())
1983 {
1984 type = primaryCalledFunction->ReturnType();
1985 }
1986 }
1987 addToNodes = prevAddToNodes;
1988 }
1989
1990 void Converter::Visit(sngcpp::ast::DotNode& dotNode)
1991 {
1992 bool prevAddToNodes = addToNodes;
1993 addToNodes = false;
1994 ConvertExpression(dotNode.Child());
1995 std::unique_ptr<sngcm::ast::Node> subject = std::move(node);
1996 sngcpp::symbols::TypeSymbol* subjectType = type;
1997 dotNode.Id()->Accept(*this);
1998 std::unique_ptr<sngcm::ast::Node> member = std::move(node);
1999 sngcpp::symbols::TypeSymbol* memberType = type;
2000 sngcpp::symbols::Symbol* parent = nullptr;
2001 if (!mappedSymbolSequence.empty())
2002 {
2003 sngcpp::symbols::Symbol* symbol = mappedSymbolSequence.back();
2004 if (symbol)
2005 {
2006 parent = symbol->Parent();
2007 if (symbol->IsFunctionGroupSymbol() && calledFunction)
2008 {
2009 symbol = calledFunction;
2010 }
2011 sngcm::ast::IdentifierNode* idNode = map.MapMemberSymbol(symbol, args);
2012 if (idNode)
2013 {
2014 node.reset(new sngcm::ast::DotNode(soulng::lexer::Span(), subject.release(), idNode));
2015 }
2016 }
2017 }
2018 if (!node)
2019 {
2020 if (dotNode.Id()->IsIdentifierNode())
2021 {
2022 node.reset(new sngcm::ast::DotNode(soulng::lexer::Span(), subject.release(),
2023 new sngcm::ast::IdentifierNode(soulng::lexer::Span(), static_cast<sngcpp::ast::IdentifierNode*>(dotNode.Id())->Identifier())));
2024 }
2025 else
2026 {
2027 node.reset(new sngcm::ast::DotNode(soulng::lexer::Span(), subject.release(),
2028 new sngcm::ast::IdentifierNode(soulng::lexer::Span(), ToUtf32(member->ToString()))));
2029 }
2030 }
2031 addToNodes = prevAddToNodes;
2032 }
2033
2034 void Converter::Visit(sngcpp::ast::ArrowNode& arrowNode)
2035 {
2036 bool prevAddToNodes = addToNodes;
2037 addToNodes = false;
2038 ConvertExpression(arrowNode.Child());
2039 std::unique_ptr<sngcm::ast::Node> subject = std::move(node);
2040 sngcpp::symbols::TypeSymbol* subjectType = type;
2041 arrowNode.Id()->Accept(*this);
2042 std::unique_ptr<sngcm::ast::Node> member = std::move(node);
2043 sngcpp::symbols::TypeSymbol* memberType = type;
2044 sngcpp::symbols::Symbol* parent = nullptr;
2045 if (!mappedSymbolSequence.empty())
2046 {
2047 sngcpp::symbols::Symbol* symbol = mappedSymbolSequence.back();
2048 if (symbol)
2049 {
2050 parent = symbol->Parent();
2051 sngcm::ast::IdentifierNode* idNode = map.MapMemberSymbol(symbol, args);
2052 if (idNode)
2053 {
2054 node.reset(new sngcm::ast::ArrowNode(soulng::lexer::Span(), subject.release(), idNode));
2055 }
2056 }
2057 }
2058 if (!node)
2059 {
2060 if (arrowNode.Id()->IsIdentifierNode())
2061 {
2062 node.reset(new sngcm::ast::ArrowNode(soulng::lexer::Span(), subject.release(),
2063 new sngcm::ast::IdentifierNode(soulng::lexer::Span(), static_cast<sngcpp::ast::IdentifierNode*>(arrowNode.Id())->Identifier())));
2064 }
2065 else
2066 {
2067 node.reset(new sngcm::ast::ArrowNode(soulng::lexer::Span(), subject.release(),
2068 new sngcm::ast::IdentifierNode(soulng::lexer::Span(), ToUtf32(member->ToString()))));
2069 }
2070 }
2071 addToNodes = prevAddToNodes;
2072 }
2073
2074 void Converter::Visit(sngcpp::ast::PostfixIncNode& postfixIncNode)
2075 {
2076 bool prevAddToNodes = addToNodes;
2077 addToNodes = false;
2078 ConvertExpression(postfixIncNode.Child());
2079 std::unique_ptr<sngcm::ast::Node> operand = std::move(node);
2080 node.reset(new sngcm::ast::PostfixIncrementNode(soulng::lexer::Span(), operand.release()));
2081 type = nullptr;
2082 addToNodes = prevAddToNodes;
2083 }
2084
2085 void Converter::Visit(sngcpp::ast::PostfixDecNode& postfixDecNode)
2086 {
2087 bool prevAddToNodes = addToNodes;
2088 addToNodes = false;
2089 ConvertExpression(postfixDecNode.Child());
2090 std::unique_ptr<sngcm::ast::Node> operand = std::move(node);
2091 node.reset(new sngcm::ast::PostfixIncrementNode(soulng::lexer::Span(), operand.release()));
2092 type = nullptr;
2093 addToNodes = prevAddToNodes;
2094 }
2095
2096 void Converter::Visit(sngcpp::ast::CppCastExpressionNode& cppCastExpressionNode)
2097 {
2098 bool prevAddToNodes = addToNodes;
2099 addToNodes = false;
2100 ConvertTypeExpression(cppCastExpressionNode.TypeExpr());
2101 std::unique_ptr<sngcm::ast::Node> typeNode = std::move(node);
2102 sngcpp::symbols::TypeSymbol* targetType = type;
2103 ConvertExpression(cppCastExpressionNode.Expr());
2104 std::unique_ptr<sngcm::ast::Node> exprNode = std::move(node);
2105 switch (cppCastExpressionNode.Op())
2106 {
2107 case sngcpp::ast::Operator::staticCast:
2108 {
2109 node.reset(new sngcm::ast::CastNode(soulng::lexer::Span(), typeNode.release(), exprNode.release()));
2110 break;
2111 }
2112 case sngcpp::ast::Operator::constCast:
2113 {
2114 WriteWarning(cppCastExpressionNode.GetSpan().line, "const_cast");
2115 node.reset(new sngcm::ast::CastNode(soulng::lexer::Span(), typeNode.release(), exprNode.release()));
2116 break;
2117 }
2118 case sngcpp::ast::Operator::dynamicCast:
2119 {
2120 NotConverted(cppCastExpressionNode.GetSpan().line, "dynamic_cast not converted");
2121 break;
2122 }
2123 case sngcpp::ast::Operator::reinterpretCast:
2124 {
2125 WriteWarning(cppCastExpressionNode.GetSpan().line, "reinterpret_cast");
2126 node.reset(new sngcm::ast::CastNode(soulng::lexer::Span(), typeNode.release(), exprNode.release()));
2127 break;
2128 }
2129 default:
2130 {
2131 NotConverted(cppCastExpressionNode.GetSpan().line, "cast operator expected");
2132 break;
2133 }
2134 }
2135 type = targetType;
2136 addToNodes = prevAddToNodes;
2137 }
2138
2139 void Converter::Visit(sngcpp::ast::TypeIdExpressionNode& typeIdExpressionNode)
2140 {
2141 NotConverted(typeIdExpressionNode.GetSpan().line, "type id expression not converted");
2142
2143 int x = 0;
2144 }
2145
2146 void Converter::Visit(sngcpp::ast::ThisNode& thisNode)
2147 {
2148 bool prevAddToNodes = addToNodes;
2149 addToNodes = false;
2150 node.reset(new sngcm::ast::ThisNode(soulng::lexer::Span()));
2151 type = AddPointer(currentClassType);
2152 addToNodes = prevAddToNodes;
2153 }
2154
2155 void Converter::Visit(sngcpp::ast::ParenthesizedExprNode& parenthesizedExprNode)
2156 {
2157 bool prevAddToNodes = addToNodes;
2158 addToNodes = false;
2159 ConvertExpression(parenthesizedExprNode.Child());
2160 std::unique_ptr<sngcm::ast::Node> exprNode = std::move(node);
2161 node.reset(new sngcm::ast::ParenthesizedExpressionNode(soulng::lexer::Span(), exprNode.release()));
2162 addToNodes = prevAddToNodes;
2163 }
2164
2165 void Converter::Visit(sngcpp::ast::LambdaExpressionNode& lambdaExpressionNode)
2166 {
2167 NotConverted(lambdaExpressionNode.GetSpan().line, "lambda not converted");
2168 type = nullptr;
2169 }
2170
2171 void Converter::Visit(sngcpp::ast::IdentifierNode& identifierNode)
2172 {
2173 sngcpp::symbols::Symbol* symbol = symbolTable.GetSymbolNothrow(&identifierNode);
2174 mappedSymbolSequence.push_back(symbol);
2175 if (symbol)
2176 {
2177 type = symbol->GetType();
2178 }
2179 else
2180 {
2181 type = nullptr;
2182 }
2183 }
2184
2185 void Converter::Visit(sngcpp::ast::OperatorFunctionIdNode& operatorFunctionIdNode)
2186 {
2187 NotConverted(operatorFunctionIdNode.GetSpan().line, "operator function id not converted");
2188
2189 int x = 0;
2190 type = nullptr;
2191 }
2192
2193 void Converter::Visit(sngcpp::ast::ConversionFunctionIdNode& conversionFunctionIdNode)
2194 {
2195 NotConverted(conversionFunctionIdNode.GetSpan().line, "conversion function id not converted");
2196
2197 int x = 0;
2198 type = nullptr;
2199 }
2200
2201 void Converter::Visit(sngcpp::ast::DtorIdNode& dDtorIdNode)
2202 {
2203 NotConverted(dDtorIdNode.GetSpan().line, "destructor id not converted");
2204
2205 int x = 0;
2206 type = nullptr;
2207 }
2208
2209 void Converter::Visit(sngcpp::ast::NestedIdNode& nestedIdNode)
2210 {
2211 nestedIdNode.Left()->Accept(*this);
2212 std::unique_ptr<sngcm::ast::Node> left(node.release());
2213 nestedIdNode.Right()->Accept(*this);
2214 if (left && !node)
2215 {
2216 if (!mappedSymbolSequence.empty())
2217 {
2218 sngcpp::symbols::Symbol* symbol = mappedSymbolSequence.back();
2219 if (symbol)
2220 {
2221 sngcm::ast::IdentifierNode* memberId = map.MapMemberSymbol(symbol, args);
2222 if (memberId)
2223 {
2224 node.reset(new sngcm::ast::DotNode(soulng::lexer::Span(), left.release(), memberId));
2225 }
2226 }
2227 }
2228 }
2229 else if (calledFunction)
2230 {
2231 if (mappedSymbolSequence.size() == 2 && mappedSymbolSequence.front() && mappedSymbolSequence.back())
2232 {
2233 if (mappedSymbolSequence.front()->IsClassGroupSymbol() && mappedSymbolSequence.back()->IsFunctionGroupSymbol())
2234 {
2235 sngcpp::symbols::ClassGroupSymbol* classGroup = static_cast<sngcpp::symbols::ClassGroupSymbol*>(mappedSymbolSequence.front());
2236 sngcpp::symbols::FunctionGroupSymbol* functionGroup = static_cast<sngcpp::symbols::FunctionGroupSymbol*>(mappedSymbolSequence.back());
2237 if (calledFunction->Name() == functionGroup->Name())
2238 {
2239 if (currentClassType)
2240 {
2241 if (currentClassType->Name() == classGroup->Name())
2242 {
2243 node.reset(new sngcm::ast::ArrowNode(soulng::lexer::Span(), new sngcm::ast::ThisNode(soulng::lexer::Span()),
2244 new sngcm::ast::IdentifierNode(soulng::lexer::Span(), functionGroup->Name())));
2245 }
2246 else if (currentClassType->BaseClasses().size() == 1 && currentClassType->BaseClasses().front()->Name() == classGroup->Name())
2247 {
2248 node.reset(new sngcm::ast::ArrowNode(soulng::lexer::Span(), new sngcm::ast::BaseNode(soulng::lexer::Span()),
2249 new sngcm::ast::IdentifierNode(soulng::lexer::Span(), functionGroup->Name())));
2250 }
2251 }
2252 }
2253 }
2254 }
2255 }
2256 }
2257
2258 void Converter::Visit(sngcpp::ast::ParameterNode& parameterNode)
2259 {
2260 ConvertTypeExpression(parameterNode.TypeExpr());
2261 std::unique_ptr<sngcm::ast::Node> typeNode(node.release());
2262 if (parameterNode.Declarator())
2263 {
2264 mappedSymbolSequence.clear();
2265 parameterNode.Declarator()->Accept(*this);
2266 }
2267 sngcm::ast::IdentifierNode* idNode = static_cast<sngcm::ast::IdentifierNode*>(node.release());
2268 std::unique_ptr<sngcm::ast::ParameterNode> paramNode(new sngcm::ast::ParameterNode(soulng::lexer::Span(), typeNode.release(), idNode));
2269 parameterNodes.push_back(std::move(paramNode));
2270 type = nullptr;
2271 }
2272
2273 void Converter::Visit(sngcpp::ast::ParameterSequenceNode& parameterSequenceNode)
2274 {
2275 parameterSequenceNode.Left()->Accept(*this);
2276 parameterSequenceNode.Right()->Accept(*this);
2277 }
2278
2279 void Converter::Visit(sngcpp::ast::FunctionNode& functionNode)
2280 {
2281 Item prevClassItem = nothrowClassItem;
2282 sngcpp::symbols::ClassTypeSymbol* prevClassType = currentClassType;
2283 sngcm::ast::Node* prevContainer = currentContainerNode;
2284 sngcm::ast::Node* functionContainer = prevContainer;
2285 sngcpp::symbols::Symbol* symbol = symbolTable.GetSymbolNothrow(&functionNode);
2286 if (excludedFunctions.find(symbol->FullName()) != excludedFunctions.cend())
2287 {
2288 if (verbose)
2289 {
2290 std::cout << "info: function " << ToUtf8(symbol->FullName()) << " excluded" << std::endl;
2291 }
2292 }
2293 else
2294 {
2295 sngcm::ast::Specifiers functionSpecifiers = MapSpecifiers(functionNode.Specifiers());
2296 std::unique_ptr<sngcm::ast::Node> typeNode;
2297 sngcpp::symbols::TypeSymbol* returnType = nullptr;
2298 if (functionNode.TypeExpr())
2299 {
2300 ConvertTypeExpression(functionNode.TypeExpr());
2301 typeNode = std::move(node);
2302 returnType = type;
2303 }
2304 mappedSymbolSequence.clear();
2305 functionNode.Declarator()->Accept(*this);
2306 if (mappedSymbolSequence.empty())
2307 {
2308 WriteWarning(functionNode.GetSpan().line, "function name not mapped");
2309 }
2310 if (!symbol)
2311 {
2312 symbol = mappedSymbolSequence.back();
2313 }
2314 if (!symbol)
2315 {
2316 currentContainerNode = prevContainer;
2317 currentClassType = prevClassType;
2318 WriteWarning(functionNode.GetSpan().line, "function name not mapped");
2319 return;
2320 }
2321 bool found = false;
2322 if (symbol->Parent()->IsClassTypeSymbol())
2323 {
2324 sngcpp::symbols::ClassTypeSymbol* classType = static_cast<sngcpp::symbols::ClassTypeSymbol*>(symbol->Parent());
2325 nothrowClassItem = Item(Item::Type::class_, classType->Name(), nothrowFileItem.include);
2326 nothrowList.ApplyTo(nothrowClassItem);
2327 if (nothrowList.Verbose())
2328 {
2329 if (nothrowClassItem.include)
2330 {
2331 std::cout << "info: " << ToUtf8(classType->Name()) << ": nothrow=true" << std::endl;
2332 }
2333 else
2334 {
2335 std::cout << "info: " << ToUtf8(classType->Name()) << ": nothrow=false" << std::endl;
2336 }
2337 }
2338 nothrowFunctionItem = Item(Item::Type::function, symbol->Name(), nothrowClassItem.include);
2339 auto cit = classMap.find(classType);
2340 if (cit != classMap.cend())
2341 {
2342 functionContainer = cit->second;
2343 currentContainerNode = functionContainer;
2344 found = true;
2345 }
2346 }
2347 else
2348 {
2349 nothrowFunctionItem = Item(Item::Type::function, symbol->Name(), nothrowFileItem.include);
2350 }
2351 if (!found)
2352 {
2353 auto it = currentContext->containerMap.find(symbol->Parent());
2354 if (it != currentContext->containerMap.cend())
2355 {
2356 functionContainer = it->second;
2357 currentContainerNode = functionContainer;
2358 }
2359 }
2360 if (symbol->IsFunctionSymbol())
2361 {
2362 nothrowList.ApplyTo(nothrowFunctionItem);
2363 if (nothrowList.Verbose())
2364 {
2365 if (nothrowFunctionItem.include)
2366 {
2367 std::cout << "info: " << ToUtf8(symbol->Name()) << ": nothrow=true" << std::endl;
2368 }
2369 else
2370 {
2371 std::cout << "info: " << ToUtf8(symbol->Name()) << ": nothrow=false" << std::endl;
2372 }
2373 }
2374 sngcpp::symbols::FunctionSymbol* functionSymbol = static_cast<sngcpp::symbols::FunctionSymbol*>(symbol);
2375 bool memberFunction = functionSymbol->Parent()->IsClassTypeSymbol();
2376 if (!currentClassType && memberFunction)
2377 {
2378 currentClassType = static_cast<sngcpp::symbols::ClassTypeSymbol*>(functionSymbol->Parent());
2379 }
2380 functionSpecifiers = functionSpecifiers | MapSpecifiers(functionSymbol->Specifiers());
2381 functionSpecifiers = functionSpecifiers | MapAccess(symbol->Access());
2382 if (nothrowFunctionItem.include)
2383 {
2384 functionSpecifiers = functionSpecifiers | sngcm::ast::Specifiers::nothrow_;
2385 }
2386 if (!memberFunction)
2387 {
2388 node.reset(new sngcm::ast::FunctionNode(soulng::lexer::Span(), functionSpecifiers, typeNode.release(), symbol->Name(), nullptr));
2389 }
2390 else
2391 {
2392 node.reset(new sngcm::ast::MemberFunctionNode(soulng::lexer::Span(), functionSpecifiers, typeNode.release(), symbol->Name(), nullptr));
2393 }
2394 }
2395 else
2396 {
2397 currentContainerNode = prevContainer;
2398 currentClassType = prevClassType;
2399 WriteWarning(functionNode.GetSpan().line, "function not created");
2400 return;
2401 }
2402 std::unique_ptr<sngcm::ast::FunctionNode> funNode(static_cast<sngcm::ast::FunctionNode*>(node.release()));
2403 for (auto& parameterNode : parameterNodes)
2404 {
2405 funNode->AddParameter(parameterNode.release());
2406 }
2407 if (functionNode.Body())
2408 {
2409 statementNodes.clear();
2410 bool prevFunctionBody = inFunctionBody;
2411 inFunctionBody = true;
2412 functionNode.Body()->Accept(*this);
2413 inFunctionBody = prevFunctionBody;
2414 if (statementNodes.size() == 1)
2415 {
2416 funNode->SetBody(static_cast<sngcm::ast::CompoundStatementNode*>(statementNodes.front().release()));
2417 }
2418 else
2419 {
2420 WriteWarning(functionNode.GetSpan().line, "function body expected");
2421 }
2422 }
2423 currentContainerNode = functionContainer;
2424 AddToContainer(functionNode.GetSpan().line, funNode.release());
2425 }
2426 currentContainerNode = prevContainer;
2427 currentClassType = prevClassType;
2428 nothrowClassItem = prevClassItem;
2429 }
2430
2431 void Converter::Visit(sngcpp::ast::FloatingLiteralNode& floatingLiteralNode)
2432 {
2433 node.reset(new sngcm::ast::DoubleLiteralNode(soulng::lexer::Span(), floatingLiteralNode.Value()));
2434 type = symbolTable.GetDoubleType();
2435 }
2436
2437 void Converter::Visit(sngcpp::ast::IntegerLiteralNode& integerLiteralNode)
2438 {
2439 if (integerLiteralNode.GetSuffix() == sngcpp::ast::Suffix::u)
2440 {
2441 node.reset(new sngcm::ast::UIntLiteralNode(soulng::lexer::Span(), integerLiteralNode.Value()));
2442 type = symbolTable.GetUIntType();
2443 }
2444 else
2445 {
2446 node.reset(new sngcm::ast::IntLiteralNode(soulng::lexer::Span(), integerLiteralNode.Value()));
2447 type = symbolTable.GetIntType();
2448 }
2449 }
2450
2451 void Converter::Visit(sngcpp::ast::CharacterLiteralNode& characterLiteralNode)
2452 {
2453 node.reset(new sngcm::ast::CharLiteralNode(soulng::lexer::Span(), characterLiteralNode.Chr()));
2454 type = symbolTable.GetCharType();
2455 }
2456
2457 void Converter::Visit(sngcpp::ast::StringLiteralNode& stringLiteralNode)
2458 {
2459 if (stringLiteralNode.EncodigPrefix() == U"U")
2460 {
2461 node.reset(new sngcm::ast::UStringLiteralNode(soulng::lexer::Span(), stringLiteralNode.Chars()));
2462 type = AddPointer(symbolTable.GetChar32Type());
2463 }
2464 else if (stringLiteralNode.EncodigPrefix() == U"u")
2465 {
2466 node.reset(new sngcm::ast::WStringLiteralNode(soulng::lexer::Span(), ToUtf16(stringLiteralNode.Chars())));
2467 type = AddPointer(symbolTable.GetChar16Type());
2468 }
2469 else
2470 {
2471 node.reset(new sngcm::ast::StringLiteralNode(soulng::lexer::Span(), ToUtf8(stringLiteralNode.Chars())));
2472 type = AddPointer(symbolTable.GetCharType());
2473 }
2474 }
2475
2476 void Converter::Visit(sngcpp::ast::BooleanLiteralNode& booleanLiteralNode)
2477 {
2478 node.reset(new sngcm::ast::BooleanLiteralNode(soulng::lexer::Span(), booleanLiteralNode.Value()));
2479 type = symbolTable.GetBoolType();
2480 }
2481
2482 void Converter::Visit(sngcpp::ast::NullPtrLiteralNode& nullPtrLiteralNode)
2483 {
2484 node.reset(new sngcm::ast::NullLiteralNode(soulng::lexer::Span()));
2485 type = AddPointer(symbolTable.GetVoidType());
2486 }
2487
2488 void Converter::Visit(sngcpp::ast::NamespaceNode& namespaceNode)
2489 {
2490 bool nsCreated = false;
2491 sngcm::ast::NamespaceNode* prevNs = currentNamespace;
2492 if (!namespaceNode.NamespaceName().empty())
2493 {
2494 std::u32string nsName = map.GetNs(namespaceNode.NamespaceName());
2495 auto it = currentContext->nsmap.find(nsName);
2496 if (it == currentContext->nsmap.cend())
2497 {
2498 currentNamespace = new sngcm::ast::NamespaceNode(Span(), new sngcm::ast::IdentifierNode(Span(), nsName));
2499 currentNamespace->SetParent(prevNs);
2500 currentContext->nsmap[nsName] = currentNamespace;
2501 currentContext->currentNamespace = currentNamespace;
2502 nsCreated = true;
2503 }
2504 else
2505 {
2506 currentNamespace = it->second;
2507 currentContext->currentNamespace = currentNamespace;
2508 }
2509 }
2510 else
2511 {
2512 currentNamespace = currentCompileUnit->GlobalNs();
2513 currentContext->currentNamespace = currentNamespace;
2514 }
2515 sngcm::ast::Node* prevContainerNode = currentContainerNode;
2516 currentContainerNode = currentNamespace;
2517 currentContext->currentContainerNode = currentContainerNode;
2518 if (namespaceNode.Child())
2519 {
2520 namespaceNode.Child()->Accept(*this);
2521 }
2522 if (prevNs && currentNamespace != currentCompileUnit->GlobalNs())
2523 {
2524 if (nsCreated)
2525 {
2526 prevNs->AddMember(currentNamespace);
2527 }
2528 }
2529 currentContainerNode = prevContainerNode;
2530 currentNamespace = prevNs;
2531 currentContext->currentNamespace = prevNs;
2532 }
2533
2534 void Converter::Visit(sngcpp::ast::SimpleTypeNode& simpleTypeNode)
2535 {
2536 sngcm::ast::NodeType nodeType = map.MapSimpleType(simpleTypeNode.Flags());
2537 node.reset(map.CreateNode(nodeType));
2538 type = symbolTable.MakeSimpleTypeSymbol(simpleTypeNode);
2539 if (!node)
2540 {
2541 NotConverted(simpleTypeNode.GetSpan().line, "simple type not converted");
2542 }
2543 }
2544
2545 void Converter::Visit(sngcpp::ast::LabeledStatementNode& labeledStatementNode)
2546 {
2547 StatementContainer prevContainer = statementContainer;
2548 statementContainer = StatementContainer::statements;
2549 labeledStatementNode.Child()->Accept(*this);
2550 sngcm::ast::StatementNode* stmt = statementNodes.back().release();
2551 statementNodes.pop_back();
2552 statementContainer = prevContainer;
2553 AddStatement(labeledStatementNode.GetSpan().line, new sngcm::ast::LabeledStatementNode(soulng::lexer::Span(), stmt));
2554 }
2555
2556 void Converter::Visit(sngcpp::ast::CaseStatementNode& caseStatementNode)
2557 {
2558 statementContainer = StatementContainer::statements;
2559 std::unique_ptr<sngcm::ast::CaseStatementNode> caseStmt(new sngcm::ast::CaseStatementNode(soulng::lexer::Span()));
2560 ConvertExpression(caseStatementNode.CaseExpr());
2561 std::unique_ptr<sngcm::ast::Node> caseExprNode = std::move(node);
2562 if (parentCaseStatementNode != nullptr)
2563 {
2564 parentCaseStatementNode->AddCaseExpr(caseExprNode.release());
2565 caseStatementNode.Child()->Accept(*this);
2566 }
2567 else
2568 {
2569 caseStmt->AddCaseExpr(caseExprNode.release());
2570 parentCaseStatementNode = caseStmt.get();
2571 int start = statementNodes.size();
2572 caseStatementNode.Child()->Accept(*this);
2573 for (int i = start; i < statementNodes.size(); ++i)
2574 {
2575 caseStmt->AddStatement(statementNodes[i].release());
2576 }
2577 statementNodes.erase(statementNodes.begin() + start, statementNodes.end());
2578 parentCaseStatementNode = nullptr;
2579 caseStatementNodes.push_back(std::move(caseStmt));
2580 }
2581 statementContainer = StatementContainer::latestCase;
2582 }
2583
2584 void Converter::Visit(sngcpp::ast::DefaultStatementNode& defaultStatementNode)
2585 {
2586 statementContainer = StatementContainer::statements;
2587 int start = statementNodes.size();
2588 defaultStatementNode.Child()->Accept(*this);
2589 sngcm::ast::DefaultStatementNode* defaultStmt = new sngcm::ast::DefaultStatementNode(soulng::lexer::Span());
2590 for (int i = start; i < statementNodes.size(); ++i)
2591 {
2592 defaultStmt->AddStatement(statementNodes[i].release());
2593 }
2594 statementNodes.erase(statementNodes.begin() + start, statementNodes.end());
2595 defaultStatement.reset(defaultStmt);
2596 statementContainer = StatementContainer::latestDefault;
2597 }
2598
2599 void Converter::Visit(sngcpp::ast::ExpressionStatementNode& expressionStatementNode)
2600 {
2601 bool prevAssignmentStatement = assignmentStatement;
2602 std::unique_ptr<sngcm::ast::Node> exprNode;
2603 if (expressionStatementNode.Child())
2604 {
2605 ConvertExpression(expressionStatementNode.Child());
2606 if (!assignmentStatement)
2607 {
2608 exprNode = std::move(node);
2609 }
2610 }
2611 if (exprNode)
2612 {
2613 if (!exprNode->IsStatementNode())
2614 {
2615 AddStatement(expressionStatementNode.GetSpan().line, new sngcm::ast::ExpressionStatementNode(soulng::lexer::Span(), exprNode.release()));
2616 }
2617 }
2618 else if (!assignmentStatement)
2619 {
2620 AddStatement(expressionStatementNode.GetSpan().line, new sngcm::ast::EmptyStatementNode(soulng::lexer::Span()));
2621 }
2622 assignmentStatement = prevAssignmentStatement;
2623 }
2624
2625 void Converter::Visit(sngcpp::ast::CompoundStatementNode& compoundStatementNode)
2626 {
2627 StatementContainer prevContainer = statementContainer;
2628 statementContainer = StatementContainer::statements;
2629 std::unique_ptr<sngcm::ast::CompoundStatementNode> compoundStmt(new sngcm::ast::CompoundStatementNode(soulng::lexer::Span()));
2630 if (compoundStatementNode.Child())
2631 {
2632 std::vector<std::std::unique_ptr<sngcm::ast::StatementNode>>prevStatementNodes=std::move(statementNodes);
2633 statementNodes.clear();
2634 compoundStatementNode.Child()->Accept(*this);
2635 for (auto& statementNode : statementNodes)
2636 {
2637 compoundStmt->AddStatement(statementNode.release());
2638 }
2639 statementNodes = std::move(prevStatementNodes);
2640 }
2641 statementContainer = prevContainer;
2642 AddStatement(compoundStatementNode.GetSpan().line, compoundStmt.release());
2643 }
2644
2645 void Converter::Visit(sngcpp::ast::StatementSequenceNode& statementSequenceNode)
2646 {
2647 statementSequenceNode.Left()->Accept(*this);
2648 statementSequenceNode.Right()->Accept(*this);
2649 }
2650
2651 void Converter::Visit(sngcpp::ast::IfStatementNode& ifStatementNode)
2652 {
2653 StatementContainer prevContainer = statementContainer;
2654 statementContainer = StatementContainer::statements;
2655 ConvertBooleanExpression(ifStatementNode.Condition());
2656 std::unique_ptr<sngcm::ast::Node> conditionNode = std::move(node);
2657 ifStatementNode.ThenS()->Accept(*this);
2658 sngcm::ast::StatementNode* thenS = statementNodes.back().release();
2659 statementNodes.pop_back();
2660 sngcm::ast::StatementNode* elseS = nullptr;
2661 if (ifStatementNode.ElseS())
2662 {
2663 ifStatementNode.ElseS()->Accept(*this);
2664 elseS = statementNodes.back().release();
2665 statementNodes.pop_back();
2666 }
2667 statementContainer = prevContainer;
2668 AddStatement(ifStatementNode.GetSpan().line, new sngcm::ast::IfStatementNode(soulng::lexer::Span(), conditionNode.release(), thenS, elseS));
2669 }
2670
2671 void Converter::Visit(sngcpp::ast::SwitchStatementNode& switchStatementNode)
2672 {
2673 StatementContainer prevContainer = statementContainer;
2674 statementContainer = StatementContainer::statements;
2675 ConvertExpression(switchStatementNode.Condition());
2676 std::unique_ptr<sngcm::ast::Node> conditionNode = std::move(node);
2677 std::vector<std::std::unique_ptr<sngcm::ast::CaseStatementNode>>prevCaseStatementNodes=std::move(caseStatementNodes);
2678 std::unique_ptr<sngcm::ast::DefaultStatementNode> prevDefaultStatementNode = std::move(defaultStatement);
2679 sngcm::ast::CaseStatementNode* prevCaseStatementNode = parentCaseStatementNode;
2680 parentCaseStatementNode = nullptr;
2681 switchStatementNode.Statement()->Accept(*this);
2682 parentCaseStatementNode = prevCaseStatementNode;
2683 sngcm::ast::StatementNode* stmt = statementNodes.back().release();
2684 statementNodes.pop_back();
2685 sngcm::ast::SwitchStatementNode* switchStatement = new sngcm::ast::SwitchStatementNode(soulng::lexer::Span(), conditionNode.release());
2686 for (auto& caseStmt : caseStatementNodes)
2687 {
2688 switchStatement->AddCase(caseStmt.release());
2689 }
2690 if (defaultStatement)
2691 {
2692 switchStatement->SetDefault(defaultStatement.release());
2693 }
2694 caseStatementNodes.clear();
2695 defaultStatement.reset();
2696 caseStatementNodes = std::move(prevCaseStatementNodes);
2697 defaultStatement = std::move(prevDefaultStatementNode);
2698 statementContainer = prevContainer;
2699 AddStatement(switchStatementNode.GetSpan().line, switchStatement);
2700 }
2701
2702 void Converter::Visit(sngcpp::ast::WhileStatementNode& whileStatementNode)
2703 {
2704 StatementContainer prevContainer = statementContainer;
2705 statementContainer = StatementContainer::statements;
2706 ConvertBooleanExpression(whileStatementNode.Condition());
2707 std::unique_ptr<sngcm::ast::Node> conditionNode = std::move(node);
2708 whileStatementNode.Statement()->Accept(*this);
2709 sngcm::ast::StatementNode* stmt = statementNodes.back().release();
2710 statementNodes.pop_back();
2711 statementContainer = prevContainer;
2712 AddStatement(whileStatementNode.GetSpan().line, new sngcm::ast::WhileStatementNode(soulng::lexer::Span(), conditionNode.release(), stmt));
2713 }
2714
2715 void Converter::Visit(sngcpp::ast::DoStatementNode& doStatementNode)
2716 {
2717 StatementContainer prevContainer = statementContainer;
2718 statementContainer = StatementContainer::statements;
2719 doStatementNode.Statement()->Accept(*this);
2720 sngcm::ast::StatementNode* stmt = statementNodes.back().release();
2721 statementNodes.pop_back();
2722 ConvertBooleanExpression(doStatementNode.Condition());
2723 std::unique_ptr<sngcm::ast::Node> conditionNode = std::move(node);
2724 statementContainer = prevContainer;
2725 AddStatement(doStatementNode.GetSpan().line, new sngcm::ast::DoStatementNode(soulng::lexer::Span(), stmt, conditionNode.release()));
2726 }
2727
2728 void Converter::Visit(sngcpp::ast::RangeForStatementNode& rangeForStatementNode)
2729 {
2730 StatementContainer prevContainer = statementContainer;
2731 statementContainer = StatementContainer::statements;
2732 bool prevRangeFor = rangeFor;
2733 rangeFor = true;
2734 rangeForStatementNode.ForRangeDeclaration()->Accept(*this);
2735 std::unique_ptr<sngcm::ast::Node> typeNode = std::move(rangeForType);
2736 if (!typeNode)
2737 {
2738 NotConverted(rangeForStatementNode.GetSpan().line, "range for type not converted");
2739 typeNode = std::move(node);
2740 }
2741 std::unique_ptr<sngcm::ast::IdentifierNode> idNode = std::move(rangeForId);
2742 if (!idNode)
2743 {
2744 NotConverted(rangeForStatementNode.GetSpan().line, "range for id not converted");
2745 idNode.reset(static_cast<sngcm::ast::IdentifierNode*>(node.release()));
2746 }
2747 ConvertExpression(rangeForStatementNode.ForRangeInitializer());
2748 rangeFor = prevRangeFor;
2749 std::unique_ptr<sngcm::ast::Node> container = std::move(node);
2750 rangeForStatementNode.Statement()->Accept(*this);
2751 std::unique_ptr<sngcm::ast::StatementNode> action = std::move(statementNodes.back());
2752 statementNodes.pop_back();
2753 statementContainer = prevContainer;
2754 AddStatement(rangeForStatementNode.GetSpan().line, new sngcm::ast::RangeForStatementNode(soulng::lexer::Span(), typeNode.release(), idNode.release(), container.release(), action.release()));
2755 }
2756
2757 void Converter::Visit(sngcpp::ast::ForStatementNode& forStatementNode)
2758 {
2759 StatementContainer prevContainer = statementContainer;
2760 statementContainer = StatementContainer::statements;
2761 forStatementNode.InitS()->Accept(*this);
2762 std::unique_ptr<sngcm::ast::StatementNode> initS(statementNodes.back().release());
2763 statementNodes.pop_back();
2764 ConvertBooleanExpression(forStatementNode.Condition());
2765 std::unique_ptr<sngcm::ast::Node> cond = std::move(node);
2766 bool prevAssingmentStatement = assignmentStatement;
2767 assignmentStatement = false;
2768 ConvertExpression(forStatementNode.LoopExpr());
2769 std::unique_ptr<sngcm::ast::StatementNode> loopS;
2770 if (!assignmentStatement)
2771 {
2772 std::unique_ptr<sngcm::ast::Node> loopExpr = std::move(node);
2773 loopS.reset(new sngcm::ast::ExpressionStatementNode(soulng::lexer::Span(), loopExpr.release()));
2774 }
2775 else
2776 {
2777 loopS = std::move(statementNodes.back());
2778 statementNodes.pop_back();
2779 }
2780 assignmentStatement = prevAssingmentStatement;
2781 forStatementNode.ActionS()->Accept(*this);
2782 std::unique_ptr<sngcm::ast::StatementNode> actionS(statementNodes.back().release());
2783 statementNodes.pop_back();
2784 statementContainer = prevContainer;
2785 AddStatement(forStatementNode.GetSpan().line, new sngcm::ast::ForStatementNode(soulng::lexer::Span(), initS.release(), cond.release(), loopS.release(), actionS.release()));
2786 }
2787
2788 void Converter::Visit(sngcpp::ast::BreakStatementNode& breakStatementNode)
2789 {
2790 AddStatement(breakStatementNode.GetSpan().line, new sngcm::ast::BreakStatementNode(soulng::lexer::Span()));
2791 }
2792
2793 void Converter::Visit(sngcpp::ast::ContinueStatementNode& continueStatementNode)
2794 {
2795 AddStatement(continueStatementNode.GetSpan().line, new sngcm::ast::ContinueStatementNode(soulng::lexer::Span()));
2796 }
2797
2798 void Converter::Visit(sngcpp::ast::ReturnStatementNode& returnStatementNode)
2799 {
2800 std::unique_ptr<sngcm::ast::Node> returnExprNode;
2801 if (returnStatementNode.ReturnExpr())
2802 {
2803 ConvertExpression(returnStatementNode.ReturnExpr());
2804 returnExprNode = std::move(node);
2805 }
2806 AddStatement(returnStatementNode.GetSpan().line, new sngcm::ast::ReturnStatementNode(soulng::lexer::Span(), returnExprNode.release()));
2807 }
2808
2809 void Converter::Visit(sngcpp::ast::GotoStatementNode& gotoStatementNode)
2810 {
2811 AddStatement(gotoStatementNode.GetSpan().line, new sngcm::ast::GotoStatementNode(soulng::lexer::Span(), gotoStatementNode.Target()));
2812 }
2813
2814 void Converter::Visit(sngcpp::ast::DeclarationStatementNode& declarationStatementNode)
2815 {
2816 declarationStatementNode.Child()->Accept(*this);
2817 }
2818
2819 void Converter::Visit(sngcpp::ast::TryStatementNode& tryStatementNode)
2820 {
2821 StatementContainer prevContainer = statementContainer;
2822 statementContainer = StatementContainer::statements;
2823 tryStatementNode.TryBlock()->Accept(*this);
2824 sngcm::ast::CompoundStatementNode* tryBlock = static_cast<sngcm::ast::CompoundStatementNode*>(statementNodes.back().release());
2825 statementNodes.pop_back();
2826 catchNodes.clear();
2827 tryStatementNode.Handlers()->Accept(*this);
2828 std::unique_ptr<sngcm::ast::TryStatementNode> tryStatement(new sngcm::ast::TryStatementNode(soulng::lexer::Span(), tryBlock));
2829 for (std::std::unique_ptr<sngcm::ast::CatchNode>&catchNode : catchNodes)
2830 {
2831 tryStatement->AddCatch(catchNode.release());
2832 }
2833 statementContainer = prevContainer;
2834 AddStatement(tryStatementNode.GetSpan().line, tryStatement.release());
2835 }
2836
2837 void Converter::Visit(sngcpp::ast::HandlerNode& handlerNode)
2838 {
2839 StatementContainer prevContainer = statementContainer;
2840 statementContainer = StatementContainer::statements;
2841 std::unique_ptr<sngcm::ast::Node> typeExpr;
2842 std::unique_ptr<sngcm::ast::IdentifierNode> id;
2843 bool prevCatchDecl = catchDecl;
2844 catchDecl = true;
2845 handlerNode.ExceptionDeclaration()->Accept(*this);
2846 typeExpr = std::move(catchType);
2847 id = std::move(catchId);
2848 catchDecl = prevCatchDecl;
2849 handlerNode.CatchBlock()->Accept(*this);
2850 sngcm::ast::CompoundStatementNode* catchBlock = static_cast<sngcm::ast::CompoundStatementNode*>(statementNodes.back().release());
2851 statementNodes.pop_back();
2852 std::unique_ptr<sngcm::ast::CatchNode> catchNode(new sngcm::ast::CatchNode(soulng::lexer::Span(), typeExpr.release(), id.release(), catchBlock));
2853 catchNodes.push_back(std::move(catchNode));
2854 statementContainer = prevContainer;
2855 }
2856
2857 void Converter::Visit(sngcpp::ast::HandlerSequenceNode& handlerSequenceNode)
2858 {
2859 handlerSequenceNode.Left()->Accept(*this);
2860 handlerSequenceNode.Right()->Accept(*this);
2861 }
2862
2863 void Converter::Visit(sngcpp::ast::CatchAllNode& catchAllNode)
2864 {
2865 NotConverted(catchAllNode.GetSpan().line, "catch all not converted");
2866 }
2867
2868 void Converter::Visit(sngcpp::ast::TypeParameterNode& typeParameterNode)
2869 {
2870 templateParameterNodes.push_back(std::unique_ptr<sngcm::ast::TemplateParameterNode>(
2871 new sngcm::ast::TemplateParameterNode(soulng::lexer::Span(), new sngcm::ast::IdentifierNode(soulng::lexer::Span(), typeParameterNode.Id()), nullptr)));
2872 }
2873
2874 void Converter::Visit(sngcpp::ast::TemplateParameterSequenceNode& templateParameterSequenceNode)
2875 {
2876 templateParameterSequenceNode.Left()->Accept(*this);
2877 templateParameterSequenceNode.Right()->Accept(*this);
2878 }
2879
2880 void Converter::Visit(sngcpp::ast::TemplateDeclarationNode& templateDeclarationNode)
2881 {
2882 std::vector<std::std::unique_ptr<sngcm::ast::TemplateParameterNode>>prevTemplateParameterNodes=std::move(templateParameterNodes);
2883 templateParameterNodes.clear();
2884 templateDeclarationNode.TemplateParameters()->Accept(*this);
2885 templateDeclarationNode.Declaration()->Accept(*this);
2886 templateParameterNodes = std::move(prevTemplateParameterNodes);
2887 }
2888
2889 void Converter::Visit(sngcpp::ast::TemplateArgumentSequenceNode& templateArgumentSequenceNode)
2890 {
2891 templateArgumentSequenceNode.Left()->Accept(*this);
2892 templateArgumentSequenceNode.Right()->Accept(*this);
2893 }
2894
2895 void Converter::Visit(sngcpp::ast::TemplateIdNode& templateIdNode)
2896 {
2897 sngcpp::symbols::Symbol* symbol = symbolTable.GetSymbolNothrow(&templateIdNode);;
2898 if (symbol)
2899 {
2900 if (symbol->IsClassTemplateSpecializationSymbol())
2901 {
2902 type = static_cast<sngcpp::symbols::ClassTemplateSpecializationSymbol*>(symbol);
2903 sngxml::dom::Document* sourceXmlDoc = nullptr;
2904 node.reset(map.MapType(type, sourceXmlDoc));
2905 }
2906 }
2907 if (!node)
2908 {
2909 NotConverted(templateIdNode.GetSpan().line, "template id converted");
2910 }
2911 }
2912
2913 void Converter::Visit(sngcpp::ast::TemplateArgumentNode& templateArgumentNode)
2914 {
2915 NotConverted(templateArgumentNode.GetSpan().line, "template argument not converted");
2916 }
2917
2918 void Converter::Visit(sngcpp::ast::ExplicitInstantiationNode& explicitInstantiationNode)
2919 {
2920 NotConverted(explicitInstantiationNode.GetSpan().line, "explicit instantiation not converted");
2921 }
2922
2923 void Converter::Visit(sngcpp::ast::ExplicitSpecializationNode& explicitSpecializationNode)
2924 {
2925 NotConverted(explicitSpecializationNode.GetSpan().line, "explicit specialization not converted");
2926 }
2927
2928 void Converter::Visit(sngcpp::ast::ConstNode& constNode)
2929 {
2930 ConvertTypeExpression(constNode.Child());
2931 node.reset(new sngcm::ast::ConstNode(soulng::lexer::Span(), node.release()));
2932 }
2933
2934 void Converter::Visit(sngcpp::ast::VolatileNode& volatileNode)
2935 {
2936 NotConverted(volatileNode.GetSpan().line, "volatile not converted");
2937 }
2938
2939 void Converter::Visit(sngcpp::ast::PointerNode& pointerNode)
2940 {
2941 ConvertTypeExpression(pointerNode.Child());
2942 node.reset(new sngcm::ast::PointerNode(soulng::lexer::Span(), node.release()));
2943 type = AddPointer(type);
2944 }
2945
2946 void Converter::Visit(sngcpp::ast::RValueRefNode& rValueRefNode)
2947 {
2948 ConvertTypeExpression(rValueRefNode.Child());
2949 node.reset(new sngcm::ast::RValueRefNode(soulng::lexer::Span(), node.release()));
2950 }
2951
2952 void Converter::Visit(sngcpp::ast::LValueRefNode& lValueRefNode)
2953 {
2954 ConvertTypeExpression(lValueRefNode.Child());
2955 node.reset(new sngcm::ast::LValueRefNode(soulng::lexer::Span(), node.release()));
2956 }
2957
2958 }