1 // =================================
   2 // Copyright () 2019 Seppo Laakko
   3 // Distributed under the MIT license
   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 // boolNode, sbyteNode, byteNode, shortNode, ushortNode, intNode, uintNode, longNode, ulongNode, floatNode, doubleNode, charNode, wcharNode, ucharNode, voidNode
  43 
  44 sngcm::ast::NodeType commonType[15][15] =
  45 {
  46     // bool
  47     {
  48         sngcm::ast::NodeType::boolNodesngcm::ast::NodeType::sbyteNodesngcm::ast::NodeType::byteNodesngcm::ast::NodeType::shortNode
  49         sngcm::ast::NodeType::ushortNodesngcm::ast::NodeType::intNodesngcm::ast::NodeType::uintNodesngcm::ast::NodeType::longNode
  50         sngcm::ast::NodeType::ulongNodesngcm::ast::NodeType::floatNodesngcm::ast::NodeType::doubleNodesngcm::ast::NodeType::charNode
  51         sngcm::ast::NodeType::wcharNodesngcm::ast::NodeType::ucharNodesngcm::ast::NodeType::voidNode
  52     }
  53     // sbyte
  54     {
  55         sngcm::ast::NodeType::sbyteNodesngcm::ast::NodeType::sbyteNodesngcm::ast::NodeType::shortNodesngcm::ast::NodeType::shortNode
  56         sngcm::ast::NodeType::intNodesngcm::ast::NodeType::intNodesngcm::ast::NodeType::longNodesngcm::ast::NodeType::longNode
  57         sngcm::ast::NodeType::ulongNodesngcm::ast::NodeType::floatNodesngcm::ast::NodeType::doubleNodesngcm::ast::NodeType::charNode
  58         sngcm::ast::NodeType::wcharNodesngcm::ast::NodeType::ucharNodesngcm::ast::NodeType::voidNode
  59     }
  60     // byte
  61     {
  62         sngcm::ast::NodeType::byteNodesngcm::ast::NodeType::shortNodesngcm::ast::NodeType::byteNodesngcm::ast::NodeType::shortNode
  63         sngcm::ast::NodeType::ushortNodesngcm::ast::NodeType::intNodesngcm::ast::NodeType::uintNodesngcm::ast::NodeType::longNode
  64         sngcm::ast::NodeType::ulongNodesngcm::ast::NodeType::floatNodesngcm::ast::NodeType::doubleNodesngcm::ast::NodeType::charNode
  65         sngcm::ast::NodeType::wcharNodesngcm::ast::NodeType::ucharNodesngcm::ast::NodeType::voidNode
  66     }
  67     // short
  68     {
  69         sngcm::ast::NodeType::shortNodesngcm::ast::NodeType::shortNodesngcm::ast::NodeType::shortNodesngcm::ast::NodeType::shortNode
  70         sngcm::ast::NodeType::intNodesngcm::ast::NodeType::intNodesngcm::ast::NodeType::longNodesngcm::ast::NodeType::longNode
  71         sngcm::ast::NodeType::ulongNodesngcm::ast::NodeType::floatNodesngcm::ast::NodeType::doubleNodesngcm::ast::NodeType::charNode
  72         sngcm::ast::NodeType::wcharNodesngcm::ast::NodeType::ucharNodesngcm::ast::NodeType::voidNode
  73     }
  74     // ushort
  75     {
  76         sngcm::ast::NodeType::ushortNodesngcm::ast::NodeType::ushortNodesngcm::ast::NodeType::ushortNodesngcm::ast::NodeType::intNode
  77         sngcm::ast::NodeType::ushortNodesngcm::ast::NodeType::intNodesngcm::ast::NodeType::uintNodesngcm::ast::NodeType::longNode
  78         sngcm::ast::NodeType::ulongNodesngcm::ast::NodeType::floatNodesngcm::ast::NodeType::doubleNodesngcm::ast::NodeType::charNode
  79         sngcm::ast::NodeType::wcharNodesngcm::ast::NodeType::ucharNodesngcm::ast::NodeType::voidNode
  80     }
  81     // int
  82     {
  83         sngcm::ast::NodeType::intNodesngcm::ast::NodeType::intNodesngcm::ast::NodeType::intNodesngcm::ast::NodeType::intNode
  84         sngcm::ast::NodeType::intNodesngcm::ast::NodeType::intNodesngcm::ast::NodeType::longNodesngcm::ast::NodeType::longNode
  85         sngcm::ast::NodeType::ulongNodesngcm::ast::NodeType::floatNodesngcm::ast::NodeType::doubleNodesngcm::ast::NodeType::charNode
  86         sngcm::ast::NodeType::wcharNodesngcm::ast::NodeType::ucharNodesngcm::ast::NodeType::voidNode
  87     }
  88     // uint
  89     {
  90         sngcm::ast::NodeType::uintNodesngcm::ast::NodeType::uintNodesngcm::ast::NodeType::uintNodesngcm::ast::NodeType::longNode
  91         sngcm::ast::NodeType::uintNodesngcm::ast::NodeType::longNodesngcm::ast::NodeType::uintNodesngcm::ast::NodeType::ulongNode
  92         sngcm::ast::NodeType::ulongNodesngcm::ast::NodeType::floatNodesngcm::ast::NodeType::doubleNodesngcm::ast::NodeType::charNode
  93         sngcm::ast::NodeType::wcharNodesngcm::ast::NodeType::ucharNodesngcm::ast::NodeType::voidNode
  94     }
  95     // long
  96     {
  97         sngcm::ast::NodeType::longNodesngcm::ast::NodeType::longNodesngcm::ast::NodeType::longNodesngcm::ast::NodeType::longNode
  98         sngcm::ast::NodeType::longNodesngcm::ast::NodeType::longNodesngcm::ast::NodeType::longNodesngcm::ast::NodeType::longNode
  99         sngcm::ast::NodeType::ulongNodesngcm::ast::NodeType::floatNodesngcm::ast::NodeType::doubleNodesngcm::ast::NodeType::charNode
 100         sngcm::ast::NodeType::wcharNodesngcm::ast::NodeType::ucharNodesngcm::ast::NodeType::voidNode
 101     }
 102     // ulong
 103     {
 104         sngcm::ast::NodeType::ulongNodesngcm::ast::NodeType::ulongNodesngcm::ast::NodeType::ulongNodesngcm::ast::NodeType::ulongNode
 105         sngcm::ast::NodeType::ulongNodesngcm::ast::NodeType::ulongNodesngcm::ast::NodeType::ulongNodesngcm::ast::NodeType::ulongNode
 106         sngcm::ast::NodeType::ulongNodesngcm::ast::NodeType::floatNodesngcm::ast::NodeType::doubleNodesngcm::ast::NodeType::charNode
 107         sngcm::ast::NodeType::wcharNodesngcm::ast::NodeType::ucharNodesngcm::ast::NodeType::voidNode
 108     }
 109     // float
 110     {
 111         sngcm::ast::NodeType::floatNodesngcm::ast::NodeType::floatNodesngcm::ast::NodeType::floatNodesngcm::ast::NodeType::floatNode
 112         sngcm::ast::NodeType::floatNodesngcm::ast::NodeType::floatNodesngcm::ast::NodeType::floatNodesngcm::ast::NodeType::floatNode
 113         sngcm::ast::NodeType::floatNodesngcm::ast::NodeType::floatNodesngcm::ast::NodeType::doubleNodesngcm::ast::NodeType::charNode
 114         sngcm::ast::NodeType::wcharNodesngcm::ast::NodeType::ucharNodesngcm::ast::NodeType::voidNode
 115     }
 116     // double
 117     {
 118         sngcm::ast::NodeType::doubleNodesngcm::ast::NodeType::doubleNodesngcm::ast::NodeType::doubleNodesngcm::ast::NodeType::doubleNode
 119         sngcm::ast::NodeType::doubleNodesngcm::ast::NodeType::doubleNodesngcm::ast::NodeType::doubleNodesngcm::ast::NodeType::doubleNode
 120         sngcm::ast::NodeType::doubleNodesngcm::ast::NodeType::doubleNodesngcm::ast::NodeType::doubleNodesngcm::ast::NodeType::charNode
 121         sngcm::ast::NodeType::wcharNodesngcm::ast::NodeType::ucharNodesngcm::ast::NodeType::voidNode
 122     }
 123     // char
 124     {
 125         sngcm::ast::NodeType::charNodesngcm::ast::NodeType::charNodesngcm::ast::NodeType::charNodesngcm::ast::NodeType::charNode
 126         sngcm::ast::NodeType::charNodesngcm::ast::NodeType::charNodesngcm::ast::NodeType::charNodesngcm::ast::NodeType::charNode
 127         sngcm::ast::NodeType::charNodesngcm::ast::NodeType::charNodesngcm::ast::NodeType::charNodesngcm::ast::NodeType::charNode
 128         sngcm::ast::NodeType::wcharNodesngcm::ast::NodeType::ucharNodesngcm::ast::NodeType::voidNode
 129     }
 130     // wchar
 131     {
 132         sngcm::ast::NodeType::wcharNodesngcm::ast::NodeType::wcharNodesngcm::ast::NodeType::wcharNodesngcm::ast::NodeType::wcharNode
 133         sngcm::ast::NodeType::wcharNodesngcm::ast::NodeType::wcharNodesngcm::ast::NodeType::wcharNodesngcm::ast::NodeType::wcharNode
 134         sngcm::ast::NodeType::wcharNodesngcm::ast::NodeType::wcharNodesngcm::ast::NodeType::wcharNodesngcm::ast::NodeType::wcharNode
 135         sngcm::ast::NodeType::wcharNodesngcm::ast::NodeType::ucharNodesngcm::ast::NodeType::voidNode
 136     }
 137     // uchar
 138     {
 139         sngcm::ast::NodeType::ucharNodesngcm::ast::NodeType::ucharNodesngcm::ast::NodeType::ucharNodesngcm::ast::NodeType::ucharNode
 140         sngcm::ast::NodeType::ucharNodesngcm::ast::NodeType::ucharNodesngcm::ast::NodeType::ucharNodesngcm::ast::NodeType::ucharNode
 141         sngcm::ast::NodeType::ucharNodesngcm::ast::NodeType::ucharNodesngcm::ast::NodeType::ucharNodesngcm::ast::NodeType::ucharNode
 142         sngcm::ast::NodeType::ucharNodesngcm::ast::NodeType::ucharNodesngcm::ast::NodeType::voidNode
 143     }
 144     // void
 145     {
 146         sngcm::ast::NodeType::voidNodesngcm::ast::NodeType::voidNodesngcm::ast::NodeType::voidNodesngcm::ast::NodeType::voidNode
 147         sngcm::ast::NodeType::voidNodesngcm::ast::NodeType::voidNodesngcm::ast::NodeType::voidNodesngcm::ast::NodeType::voidNode
 148         sngcm::ast::NodeType::voidNodesngcm::ast::NodeType::voidNodesngcm::ast::NodeType::voidNodesngcm::ast::NodeType::voidNode
 149         sngcm::ast::NodeType::voidNodesngcm::ast::NodeType::voidNodesngcm::ast::NodeType::voidNode
 150     }
 151 };
 152 
 153 // boolNode, sbyteNode, byteNode, shortNode, ushortNode, intNode, uintNode, longNode, ulongNode, floatNode, doubleNode, charNode, wcharNode, ucharNode, voidNode
 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&nothrowList_):
 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::fileU""false)nothrowClassItem(Item::Type::class_U""false)nothrowFunctionItem(Item::Type::functionU""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(fileNamecu->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(indexnew sngcm::ast::NamespaceImportNode(soulng::lexer::Span()new sngcm::ast::IdentifierNode(soulng::lexer::Span()namespaceImport)));
 212         ++index;
 213     }
 214 }
 215 
 216 void Converter::AddToContainer(int linesngcm::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 linesngcm::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 lineconst 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(typeSymbolsourceXmlDoc));
 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(calledFunctionargs));
 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(typeSymbolsourceXmlDoc));
 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(classTypeSymbolsourceXmlDoc));
 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 lineconst std::string& message)
 470 {
 471     WriteWarning(linemessage);
 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(typeSymbolsourceXmlDoc);
 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* leftTypesngcpp::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(derivationspointeeType->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(derivationsptrType->BaseType());
 732                 }
 733             }
 734         }
 735     }
 736     return ptrType;
 737 }
 738 
 739 sngcpp::symbols::TypeSymbol* Converter::MakeElementType(sngcpp::symbols::TypeSymbol* arrayType)
 740 {
 741     // todo
 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(baseClassTypesourceXmlDoc));
 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().linecls.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(typeSymbolsourceXmlDoc));
 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().linenode.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(returnTypeSymbolsourceXmlDoc));
 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()functionSpecifiersreturnTypeNode.release()
 938                         functionSymbol->GroupName()nullptr);
 939                     for (auto& parameterNode : parameterNodes)
 940                     {
 941                         memberFunctionNode->AddParameter(parameterNode.release());
 942                     }
 943                     AddToContainer(memberDeclarationNode.GetSpan().linememberFunctionNode);
 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::functionsymbol->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::functionsymbol->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()memberFunctionSpecifiersnullptr));
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()memberFunctionSpecifiersnullptr));
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().linefunctionNode.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::fileToUtf32(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(targetDirsourceFileName));
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(0new 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(1new 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().linenode.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().lineconstructionStatement);
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().lineconstructionStatement);
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     // todo
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     // todo
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().lineenumeratedTypeNode.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     // todo
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().linestmt);
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     // todo
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().linenew 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(leftTyperightType);
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(leftTyperightType);
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(leftTyperightType);
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(leftTyperightType);
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(leftTyperightType);
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(leftTyperightType);
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     // todo
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().linenew 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(calledFunctionargs));
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(symbolargs);
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(symbolargs);
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     // todo
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     // todo
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     // todo
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     // todo
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(symbolargs);
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::functionsymbol->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::functionsymbol->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()functionSpecifierstypeNode.release()symbol->Name()nullptr));
2389             }
2390             else
2391             {
2392                 node.reset(new sngcm::ast::MemberFunctionNode(soulng::lexer::Span()functionSpecifierstypeNode.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().linefunNode.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().linenew 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() + startstatementNodes.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() + startstatementNodes.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().linenew sngcm::ast::ExpressionStatementNode(soulng::lexer::Span()exprNode.release()));
2616         }
2617     }
2618     else if (!assignmentStatement)
2619     {
2620         AddStatement(expressionStatementNode.GetSpan().linenew 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().linecompoundStmt.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().linenew sngcm::ast::IfStatementNode(soulng::lexer::Span()conditionNode.release()thenSelseS));
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().lineswitchStatement);
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().linenew 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().linenew sngcm::ast::DoStatementNode(soulng::lexer::Span()stmtconditionNode.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().linenew 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().linenew 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().linenew sngcm::ast::BreakStatementNode(soulng::lexer::Span()));
2791 }
2792 
2793 void Converter::Visit(sngcpp::ast::ContinueStatementNode& continueStatementNode)
2794 {
2795     AddStatement(continueStatementNode.GetSpan().linenew 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().linenew sngcm::ast::ReturnStatementNode(soulng::lexer::Span()returnExprNode.release()));
2807 }
2808 
2809 void Converter::Visit(sngcpp::ast::GotoStatementNode& gotoStatementNode)
2810 {
2811     AddStatement(gotoStatementNode.GetSpan().linenew 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().linetryStatement.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(typesourceXmlDoc));
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 } // namespace cpp2cm