From 405cbcbf0cb4f8f77881387d819460538074b68d Mon Sep 17 00:00:00 2001 From: Roberto Raggi Date: Wed, 27 Aug 2025 18:27:34 +0200 Subject: [PATCH 1/2] Split the AST interpreter --- src/parser/CMakeLists.txt | 7 + src/parser/cxx/ast_interpreter.cc | 3469 +---------------- src/parser/cxx/ast_interpreter.h | 200 +- .../cxx/ast_interpreter_declarations.cc | 575 +++ src/parser/cxx/ast_interpreter_declarators.cc | 429 ++ src/parser/cxx/ast_interpreter_expressions.cc | 1471 +++++++ src/parser/cxx/ast_interpreter_names.cc | 219 ++ src/parser/cxx/ast_interpreter_specifiers.cc | 557 +++ src/parser/cxx/ast_interpreter_statements.cc | 276 ++ src/parser/cxx/ast_interpreter_units.cc | 146 + 10 files changed, 3786 insertions(+), 3563 deletions(-) create mode 100644 src/parser/cxx/ast_interpreter_declarations.cc create mode 100644 src/parser/cxx/ast_interpreter_declarators.cc create mode 100644 src/parser/cxx/ast_interpreter_expressions.cc create mode 100644 src/parser/cxx/ast_interpreter_names.cc create mode 100644 src/parser/cxx/ast_interpreter_specifiers.cc create mode 100644 src/parser/cxx/ast_interpreter_statements.cc create mode 100644 src/parser/cxx/ast_interpreter_units.cc diff --git a/src/parser/CMakeLists.txt b/src/parser/CMakeLists.txt index 840c70b6..faeca0f3 100644 --- a/src/parser/CMakeLists.txt +++ b/src/parser/CMakeLists.txt @@ -22,6 +22,13 @@ file(GLOB CXX_VIEWS_INCLUDE_HEADER_FILES cxx/views/*.h) add_library(cxx-parser cxx/ast_cursor.cc + cxx/ast_interpreter_declarations.cc + cxx/ast_interpreter_declarators.cc + cxx/ast_interpreter_expressions.cc + cxx/ast_interpreter_names.cc + cxx/ast_interpreter_specifiers.cc + cxx/ast_interpreter_statements.cc + cxx/ast_interpreter_units.cc cxx/ast_interpreter.cc cxx/ast_pretty_printer.cc cxx/ast_printer.cc diff --git a/src/parser/cxx/ast_interpreter.cc b/src/parser/cxx/ast_interpreter.cc index a0765bdd..2a2e09bd 100644 --- a/src/parser/cxx/ast_interpreter.cc +++ b/src/parser/cxx/ast_interpreter.cc @@ -81,94 +81,6 @@ struct ArithmeticCast { } // namespace -struct ASTInterpreter::UnitResult {}; - -struct ASTInterpreter::DeclarationResult {}; - -struct ASTInterpreter::StatementResult {}; - -struct ASTInterpreter::TemplateParameterResult {}; - -struct ASTInterpreter::SpecifierResult {}; - -struct ASTInterpreter::PtrOperatorResult {}; - -struct ASTInterpreter::CoreDeclaratorResult {}; - -struct ASTInterpreter::DeclaratorChunkResult {}; - -struct ASTInterpreter::UnqualifiedIdResult {}; - -struct ASTInterpreter::NestedNameSpecifierResult {}; - -struct ASTInterpreter::FunctionBodyResult {}; - -struct ASTInterpreter::TemplateArgumentResult {}; - -struct ASTInterpreter::ExceptionSpecifierResult {}; - -struct ASTInterpreter::RequirementResult {}; - -struct ASTInterpreter::NewInitializerResult {}; - -struct ASTInterpreter::MemInitializerResult {}; - -struct ASTInterpreter::LambdaCaptureResult {}; - -struct ASTInterpreter::ExceptionDeclarationResult {}; - -struct ASTInterpreter::AttributeSpecifierResult {}; - -struct ASTInterpreter::AttributeTokenResult {}; - -struct ASTInterpreter::GlobalModuleFragmentResult {}; - -struct ASTInterpreter::PrivateModuleFragmentResult {}; - -struct ASTInterpreter::ModuleDeclarationResult {}; - -struct ASTInterpreter::ModuleNameResult {}; - -struct ASTInterpreter::ModuleQualifierResult {}; - -struct ASTInterpreter::ModulePartitionResult {}; - -struct ASTInterpreter::ImportNameResult {}; - -struct ASTInterpreter::InitDeclaratorResult {}; - -struct ASTInterpreter::DeclaratorResult {}; - -struct ASTInterpreter::UsingDeclaratorResult {}; - -struct ASTInterpreter::EnumeratorResult {}; - -struct ASTInterpreter::TypeIdResult {}; - -struct ASTInterpreter::HandlerResult {}; - -struct ASTInterpreter::BaseSpecifierResult {}; - -struct ASTInterpreter::RequiresClauseResult {}; - -struct ASTInterpreter::ParameterDeclarationClauseResult {}; - -struct ASTInterpreter::TrailingReturnTypeResult {}; - -struct ASTInterpreter::LambdaSpecifierResult {}; - -struct ASTInterpreter::TypeConstraintResult {}; - -struct ASTInterpreter::AttributeArgumentClauseResult {}; - -struct ASTInterpreter::AttributeResult {}; - -struct ASTInterpreter::AttributeUsingPrefixResult {}; - -struct ASTInterpreter::NewPlacementResult {}; - -struct ASTInterpreter::NestedNamespaceSpecifierResult {}; - struct ASTInterpreter::ToBool { ASTInterpreter& interp; @@ -185,3385 +97,6 @@ struct ASTInterpreter::ToBool { } }; -struct ASTInterpreter::UnitVisitor { - ASTInterpreter& accept; - - [[nodiscard]] auto operator()(TranslationUnitAST* ast) -> UnitResult; - - [[nodiscard]] auto operator()(ModuleUnitAST* ast) -> UnitResult; -}; - -struct ASTInterpreter::DeclarationVisitor { - ASTInterpreter& accept; - - [[nodiscard]] auto operator()(SimpleDeclarationAST* ast) -> DeclarationResult; - - [[nodiscard]] auto operator()(AsmDeclarationAST* ast) -> DeclarationResult; - - [[nodiscard]] auto operator()(NamespaceAliasDefinitionAST* ast) - -> DeclarationResult; - - [[nodiscard]] auto operator()(UsingDeclarationAST* ast) -> DeclarationResult; - - [[nodiscard]] auto operator()(UsingEnumDeclarationAST* ast) - -> DeclarationResult; - - [[nodiscard]] auto operator()(UsingDirectiveAST* ast) -> DeclarationResult; - - [[nodiscard]] auto operator()(StaticAssertDeclarationAST* ast) - -> DeclarationResult; - - [[nodiscard]] auto operator()(AliasDeclarationAST* ast) -> DeclarationResult; - - [[nodiscard]] auto operator()(OpaqueEnumDeclarationAST* ast) - -> DeclarationResult; - - [[nodiscard]] auto operator()(FunctionDefinitionAST* ast) - -> DeclarationResult; - - [[nodiscard]] auto operator()(TemplateDeclarationAST* ast) - -> DeclarationResult; - - [[nodiscard]] auto operator()(ConceptDefinitionAST* ast) -> DeclarationResult; - - [[nodiscard]] auto operator()(DeductionGuideAST* ast) -> DeclarationResult; - - [[nodiscard]] auto operator()(ExplicitInstantiationAST* ast) - -> DeclarationResult; - - [[nodiscard]] auto operator()(ExportDeclarationAST* ast) -> DeclarationResult; - - [[nodiscard]] auto operator()(ExportCompoundDeclarationAST* ast) - -> DeclarationResult; - - [[nodiscard]] auto operator()(LinkageSpecificationAST* ast) - -> DeclarationResult; - - [[nodiscard]] auto operator()(NamespaceDefinitionAST* ast) - -> DeclarationResult; - - [[nodiscard]] auto operator()(EmptyDeclarationAST* ast) -> DeclarationResult; - - [[nodiscard]] auto operator()(AttributeDeclarationAST* ast) - -> DeclarationResult; - - [[nodiscard]] auto operator()(ModuleImportDeclarationAST* ast) - -> DeclarationResult; - - [[nodiscard]] auto operator()(ParameterDeclarationAST* ast) - -> DeclarationResult; - - [[nodiscard]] auto operator()(AccessDeclarationAST* ast) -> DeclarationResult; - - [[nodiscard]] auto operator()(ForRangeDeclarationAST* ast) - -> DeclarationResult; - - [[nodiscard]] auto operator()(StructuredBindingDeclarationAST* ast) - -> DeclarationResult; -}; - -struct ASTInterpreter::StatementVisitor { - ASTInterpreter& accept; - - [[nodiscard]] auto operator()(LabeledStatementAST* ast) -> StatementResult; - - [[nodiscard]] auto operator()(CaseStatementAST* ast) -> StatementResult; - - [[nodiscard]] auto operator()(DefaultStatementAST* ast) -> StatementResult; - - [[nodiscard]] auto operator()(ExpressionStatementAST* ast) -> StatementResult; - - [[nodiscard]] auto operator()(CompoundStatementAST* ast) -> StatementResult; - - [[nodiscard]] auto operator()(IfStatementAST* ast) -> StatementResult; - - [[nodiscard]] auto operator()(ConstevalIfStatementAST* ast) - -> StatementResult; - - [[nodiscard]] auto operator()(SwitchStatementAST* ast) -> StatementResult; - - [[nodiscard]] auto operator()(WhileStatementAST* ast) -> StatementResult; - - [[nodiscard]] auto operator()(DoStatementAST* ast) -> StatementResult; - - [[nodiscard]] auto operator()(ForRangeStatementAST* ast) -> StatementResult; - - [[nodiscard]] auto operator()(ForStatementAST* ast) -> StatementResult; - - [[nodiscard]] auto operator()(BreakStatementAST* ast) -> StatementResult; - - [[nodiscard]] auto operator()(ContinueStatementAST* ast) -> StatementResult; - - [[nodiscard]] auto operator()(ReturnStatementAST* ast) -> StatementResult; - - [[nodiscard]] auto operator()(CoroutineReturnStatementAST* ast) - -> StatementResult; - - [[nodiscard]] auto operator()(GotoStatementAST* ast) -> StatementResult; - - [[nodiscard]] auto operator()(DeclarationStatementAST* ast) - -> StatementResult; - - [[nodiscard]] auto operator()(TryBlockStatementAST* ast) -> StatementResult; -}; - -struct ASTInterpreter::ExpressionVisitor { - ASTInterpreter& accept; - - [[nodiscard]] auto unit() -> TranslationUnit* { return accept.unit_; } - - [[nodiscard]] auto control() -> Control* { return accept.control(); } - - [[nodiscard]] auto memoryLayout() -> MemoryLayout* { - return control()->memoryLayout(); - } - - [[nodiscard]] auto evaluate(ExpressionAST* ast) -> ExpressionResult { - return accept(ast); - } - - [[nodiscard]] auto toBool(const ConstValue& value) -> bool { - return accept.toBool(value).value_or(false); - } - - [[nodiscard]] auto toInt(const ConstValue& value) -> std::intmax_t { - return accept.toInt(value).value_or(0); - } - - [[nodiscard]] auto toInt32(const ConstValue& value) -> std::int32_t { - return static_cast(toInt(value)); - } - - [[nodiscard]] auto toInt64(const ConstValue& value) -> std::int64_t { - return static_cast(toInt(value)); - } - - [[nodiscard]] auto toUInt(const ConstValue& value) -> std::uintmax_t { - return accept.toUInt(value).value_or(0); - } - - [[nodiscard]] auto toUInt32(const ConstValue& value) -> std::uint32_t { - return static_cast(toUInt(value)); - } - - [[nodiscard]] auto toUInt64(const ConstValue& value) -> std::uint64_t { - return static_cast(toUInt(value)); - } - - [[nodiscard]] auto toFloat(const ConstValue& value) -> float { - return accept.toFloat(value).value_or(0.0f); - } - - [[nodiscard]] auto toDouble(const ConstValue& value) -> double { - return accept.toDouble(value).value_or(0.0); - } - - [[nodiscard]] auto toValue(std::uintmax_t value) -> ConstValue { - return ConstValue(std::bit_cast(value)); - } - - auto star_op(BinaryExpressionAST* ast, const ExpressionResult& left, - const ExpressionResult& right) -> ExpressionResult { - const auto type = ast->leftExpression->type; - const auto sz = memoryLayout()->sizeOf(type); - - if (control()->is_floating_point(type)) { - return toDouble(*left) * toDouble(*right); - } - - if (control()->is_unsigned(type)) { - if (sz <= 4) return toValue(toUInt32(*left) * toUInt32(*right)); - return toValue(toUInt64(*left) * toUInt64(*right)); - } - - if (sz <= 4) return toValue(toInt32(*left) * toInt32(*right)); - return toValue(toInt64(*left) * toInt64(*right)); - } - - auto slash_op(BinaryExpressionAST* ast, const ExpressionResult& left, - const ExpressionResult& right) -> ExpressionResult { - const auto type = ast->leftExpression->type; - const auto sz = memoryLayout()->sizeOf(type); - - if (control()->is_floating_point(type)) { - auto l = toDouble(*left); - auto r = toDouble(*right); - if (r == 0.0) return std::nullopt; - return l / r; - } - - if (control()->is_unsigned(type)) { - if (sz <= 4) { - auto l = toUInt32(*left); - auto r = toUInt32(*right); - if (r == 0) return std::nullopt; - return toValue(l / r); - } - - auto l = toUInt64(*left); - auto r = toUInt64(*right); - if (r == 0) return std::nullopt; - return toValue(l / r); - } - - if (sz <= 4) { - auto l = toInt32(*left); - auto r = toInt32(*right); - if (r == 0) return std::nullopt; - return toValue(l / r); - } - - auto l = toInt64(*left); - auto r = toInt64(*right); - if (r == 0) return std::nullopt; - return toValue(l / r); - } - - auto percent_op(BinaryExpressionAST* ast, const ExpressionResult& left, - const ExpressionResult& right) -> ExpressionResult { - const auto type = ast->leftExpression->type; - const auto sz = memoryLayout()->sizeOf(type); - - if (control()->is_unsigned(type)) { - if (sz <= 4) { - auto l = toUInt32(*left); - auto r = toUInt32(*right); - if (r == 0) return std::nullopt; - return toValue(l % r); - } - - auto l = toUInt64(*left); - auto r = toUInt64(*right); - if (r == 0) return std::nullopt; - return toValue(l % r); - } - - if (sz <= 4) { - auto l = toInt32(*left); - auto r = toInt32(*right); - if (r == 0) return std::nullopt; - return toValue(l % r); - } - - auto l = toInt64(*left); - auto r = toInt64(*right); - if (r == 0) return std::nullopt; - return toValue(l % r); - } - - auto plus_op(BinaryExpressionAST* ast, const ExpressionResult& left, - const ExpressionResult& right) -> ExpressionResult { - const auto type = ast->leftExpression->type; - const auto sz = memoryLayout()->sizeOf(type); - - if (control()->is_floating_point(type)) { - return toDouble(*left) + toDouble(*right); - } - - if (control()->is_unsigned(type)) { - if (sz <= 4) return toValue(toUInt32(*left) + toUInt32(*right)); - return toValue(toUInt64(*left) + toUInt64(*right)); - } - - if (sz <= 4) return toValue(toInt32(*left) + toInt32(*right)); - return toValue(toInt64(*left) + toInt64(*right)); - } - - auto minus_op(BinaryExpressionAST* ast, const ExpressionResult& left, - const ExpressionResult& right) -> ExpressionResult { - const auto type = ast->leftExpression->type; - const auto sz = memoryLayout()->sizeOf(type); - - if (control()->is_floating_point(type)) { - return toDouble(*left) - toDouble(*right); - } - - if (control()->is_unsigned(type)) { - if (sz <= 4) return toValue(toUInt32(*left) - toUInt32(*right)); - return toValue(toUInt64(*left) - toUInt64(*right)); - } - - if (sz <= 4) return toValue(toInt32(*left) - toInt32(*right)); - return toValue(toInt64(*left) - toInt64(*right)); - } - - auto less_less_op(BinaryExpressionAST* ast, const ExpressionResult& left, - const ExpressionResult& right) -> ExpressionResult { - const auto type = ast->leftExpression->type; - const auto sz = memoryLayout()->sizeOf(type); - - if (control()->is_unsigned(type)) { - if (sz <= 4) return toValue(toUInt32(*left) << toUInt32(*right)); - return toValue(toUInt64(*left) << toUInt64(*right)); - } - - if (sz <= 4) return toValue(toInt32(*left) << toInt32(*right)); - return toValue(toInt64(*left) << toInt64(*right)); - } - - auto greater_greater_op(BinaryExpressionAST* ast, - const ExpressionResult& left, - const ExpressionResult& right) -> ExpressionResult { - const auto type = ast->leftExpression->type; - const auto sz = memoryLayout()->sizeOf(type); - - if (control()->is_unsigned(type)) { - if (sz <= 4) return toValue(toUInt32(*left) >> toUInt32(*right)); - return toValue(toUInt64(*left) >> toUInt64(*right)); - } - - if (sz <= 4) return toValue(toInt32(*left) >> toInt32(*right)); - return toValue(toInt64(*left) >> toInt64(*right)); - } - - auto less_equal_greater_op(BinaryExpressionAST* ast, - const ExpressionResult& left, - const ExpressionResult& right) - -> ExpressionResult { - auto convert = [](std::partial_ordering cmp) -> int { - if (cmp < 0) return -1; - if (cmp > 0) return 1; - return 0; - }; - - const auto type = ast->leftExpression->type; - const auto sz = memoryLayout()->sizeOf(type); - - if (control()->is_floating_point(type)) - return convert(toDouble(*left) <=> toDouble(*right)); - - if (control()->is_unsigned(type)) { - if (sz <= 4) return convert(toUInt32(*left) <=> toUInt32(*right)); - return convert(toUInt64(*left) <=> toUInt64(*right)); - } - - if (sz <= 4) return convert(toInt32(*left) <=> toInt32(*right)); - return convert(toInt64(*left) <=> toInt64(*right)); - } - - auto less_equal_op(BinaryExpressionAST* ast, const ExpressionResult& left, - const ExpressionResult& right) -> ExpressionResult { - const auto type = ast->leftExpression->type; - const auto sz = memoryLayout()->sizeOf(type); - - if (control()->is_floating_point(type)) - return toDouble(*left) <= toDouble(*right); - - if (control()->is_unsigned(type)) { - if (sz <= 4) return toUInt(*left) <= toUInt(*right); - return toUInt64(*left) <= toUInt64(*right); - } - - if (sz <= 4) return toInt(*left) <= toInt(*right); - return toInt64(*left) <= toInt64(*right); - } - - auto greater_equal_op(BinaryExpressionAST* ast, const ExpressionResult& left, - const ExpressionResult& right) -> ExpressionResult { - const auto type = ast->leftExpression->type; - const auto sz = memoryLayout()->sizeOf(type); - - if (control()->is_floating_point(type)) - return toDouble(*left) >= toDouble(*right); - - if (control()->is_unsigned(type)) { - if (sz <= 4) return toUInt(*left) >= toUInt(*right); - return toUInt64(*left) >= toUInt64(*right); - } - - if (sz <= 4) return toInt(*left) >= toInt(*right); - return toInt64(*left) >= toInt64(*right); - } - - auto less_op(BinaryExpressionAST* ast, const ExpressionResult& left, - const ExpressionResult& right) -> ExpressionResult { - const auto type = ast->leftExpression->type; - const auto sz = memoryLayout()->sizeOf(type); - - if (control()->is_floating_point(type)) - return toDouble(*left) < toDouble(*right); - - if (control()->is_unsigned(type)) { - if (sz <= 4) return toUInt(*left) < toUInt(*right); - return toUInt64(*left) < toUInt64(*right); - } - - if (sz <= 4) return toInt(*left) < toInt(*right); - return toInt64(*left) < toInt64(*right); - } - - auto greater_op(BinaryExpressionAST* ast, const ExpressionResult& left, - const ExpressionResult& right) -> ExpressionResult { - const auto type = ast->leftExpression->type; - const auto sz = memoryLayout()->sizeOf(type); - - if (control()->is_floating_point(type)) - return toDouble(*left) > toDouble(*right); - - if (control()->is_unsigned(type)) { - if (sz <= 4) return toUInt(*left) > toUInt(*right); - return toUInt64(*left) > toUInt64(*right); - } - - if (sz <= 4) return toInt(*left) > toInt(*right); - return toInt64(*left) > toInt64(*right); - } - - auto equal_equal_op(BinaryExpressionAST* ast, const ExpressionResult& left, - const ExpressionResult& right) -> ExpressionResult { - const auto type = ast->leftExpression->type; - const auto sz = memoryLayout()->sizeOf(type); - - if (control()->is_floating_point(type)) - return toDouble(*left) == toDouble(*right); - - if (control()->is_unsigned(type)) { - if (sz <= 4) return toUInt(*left) == toUInt(*right); - return toUInt64(*left) == toUInt64(*right); - } - - if (sz <= 4) return toInt(*left) == toInt(*right); - return toInt64(*left) == toInt64(*right); - } - - auto exclaim_equal_op(BinaryExpressionAST* ast, const ExpressionResult& left, - const ExpressionResult& right) -> ExpressionResult { - const auto type = ast->leftExpression->type; - const auto sz = memoryLayout()->sizeOf(type); - - if (control()->is_floating_point(type)) - return toDouble(*left) != toDouble(*right); - - if (control()->is_unsigned(type)) { - if (sz <= 4) return toUInt(*left) != toUInt(*right); - return toUInt64(*left) != toUInt64(*right); - } - - if (sz <= 4) return toInt(*left) != toInt(*right); - return toInt64(*left) != toInt64(*right); - } - - auto amp_op(BinaryExpressionAST* ast, const ExpressionResult& left, - const ExpressionResult& right) -> ExpressionResult { - return toInt(*left) & toInt(*right); - } - - auto caret_op(BinaryExpressionAST* ast, const ExpressionResult& left, - const ExpressionResult& right) -> ExpressionResult { - return toInt(*left) ^ toInt(*right); - } - - auto bar_op(BinaryExpressionAST* ast, const ExpressionResult& left, - const ExpressionResult& right) -> ExpressionResult { - return toInt(*left) | toInt(*right); - } - - auto amp_amp_op(BinaryExpressionAST* ast, const ExpressionResult& left, - const ExpressionResult& right) -> ExpressionResult { - return toBool(*left) && toBool(*right); - } - - auto bar_bar_op(BinaryExpressionAST* ast, const ExpressionResult& left, - const ExpressionResult& right) -> ExpressionResult { - return toBool(*left) || toBool(*right); - } - - auto comma_op(BinaryExpressionAST* ast, const ExpressionResult& left, - const ExpressionResult& right) -> ExpressionResult { - // Comma operator returns the right operand - return right; - } - - [[nodiscard]] auto operator()(CharLiteralExpressionAST* ast) - -> ExpressionResult; - - [[nodiscard]] auto operator()(BoolLiteralExpressionAST* ast) - -> ExpressionResult; - - [[nodiscard]] auto operator()(IntLiteralExpressionAST* ast) - -> ExpressionResult; - - [[nodiscard]] auto operator()(FloatLiteralExpressionAST* ast) - -> ExpressionResult; - - [[nodiscard]] auto operator()(NullptrLiteralExpressionAST* ast) - -> ExpressionResult; - - [[nodiscard]] auto operator()(StringLiteralExpressionAST* ast) - -> ExpressionResult; - - [[nodiscard]] auto operator()(UserDefinedStringLiteralExpressionAST* ast) - -> ExpressionResult; - - [[nodiscard]] auto operator()(ObjectLiteralExpressionAST* ast) - -> ExpressionResult; - - [[nodiscard]] auto operator()(ThisExpressionAST* ast) -> ExpressionResult; - - [[nodiscard]] auto operator()(GenericSelectionExpressionAST* ast) - -> ExpressionResult; - - [[nodiscard]] auto operator()(NestedStatementExpressionAST* ast) - -> ExpressionResult; - - [[nodiscard]] auto operator()(NestedExpressionAST* ast) -> ExpressionResult; - - [[nodiscard]] auto operator()(IdExpressionAST* ast) -> ExpressionResult; - - [[nodiscard]] auto operator()(LambdaExpressionAST* ast) -> ExpressionResult; - - [[nodiscard]] auto operator()(FoldExpressionAST* ast) -> ExpressionResult; - - [[nodiscard]] auto operator()(RightFoldExpressionAST* ast) - -> ExpressionResult; - - [[nodiscard]] auto operator()(LeftFoldExpressionAST* ast) -> ExpressionResult; - - [[nodiscard]] auto operator()(RequiresExpressionAST* ast) -> ExpressionResult; - - [[nodiscard]] auto operator()(VaArgExpressionAST* ast) -> ExpressionResult; - - [[nodiscard]] auto operator()(SubscriptExpressionAST* ast) - -> ExpressionResult; - - [[nodiscard]] auto operator()(CallExpressionAST* ast) -> ExpressionResult; - - [[nodiscard]] auto operator()(TypeConstructionAST* ast) -> ExpressionResult; - - [[nodiscard]] auto operator()(BracedTypeConstructionAST* ast) - -> ExpressionResult; - - [[nodiscard]] auto operator()(SpliceMemberExpressionAST* ast) - -> ExpressionResult; - - [[nodiscard]] auto operator()(MemberExpressionAST* ast) -> ExpressionResult; - - [[nodiscard]] auto operator()(PostIncrExpressionAST* ast) -> ExpressionResult; - - [[nodiscard]] auto operator()(CppCastExpressionAST* ast) -> ExpressionResult; - - [[nodiscard]] auto operator()(BuiltinBitCastExpressionAST* ast) - -> ExpressionResult; - - [[nodiscard]] auto operator()(BuiltinOffsetofExpressionAST* ast) - -> ExpressionResult; - - [[nodiscard]] auto operator()(TypeidExpressionAST* ast) -> ExpressionResult; - - [[nodiscard]] auto operator()(TypeidOfTypeExpressionAST* ast) - -> ExpressionResult; - - [[nodiscard]] auto operator()(SpliceExpressionAST* ast) -> ExpressionResult; - - [[nodiscard]] auto operator()(GlobalScopeReflectExpressionAST* ast) - -> ExpressionResult; - - [[nodiscard]] auto operator()(NamespaceReflectExpressionAST* ast) - -> ExpressionResult; - - [[nodiscard]] auto operator()(TypeIdReflectExpressionAST* ast) - -> ExpressionResult; - - [[nodiscard]] auto operator()(ReflectExpressionAST* ast) -> ExpressionResult; - - [[nodiscard]] auto operator()(LabelAddressExpressionAST* ast) - -> ExpressionResult; - - [[nodiscard]] auto operator()(UnaryExpressionAST* ast) -> ExpressionResult; - - [[nodiscard]] auto operator()(AwaitExpressionAST* ast) -> ExpressionResult; - - [[nodiscard]] auto operator()(SizeofExpressionAST* ast) -> ExpressionResult; - - [[nodiscard]] auto operator()(SizeofTypeExpressionAST* ast) - -> ExpressionResult; - - [[nodiscard]] auto operator()(SizeofPackExpressionAST* ast) - -> ExpressionResult; - - [[nodiscard]] auto operator()(AlignofTypeExpressionAST* ast) - -> ExpressionResult; - - [[nodiscard]] auto operator()(AlignofExpressionAST* ast) -> ExpressionResult; - - [[nodiscard]] auto operator()(NoexceptExpressionAST* ast) -> ExpressionResult; - - [[nodiscard]] auto operator()(NewExpressionAST* ast) -> ExpressionResult; - - [[nodiscard]] auto operator()(DeleteExpressionAST* ast) -> ExpressionResult; - - [[nodiscard]] auto operator()(CastExpressionAST* ast) -> ExpressionResult; - - [[nodiscard]] auto operator()(ImplicitCastExpressionAST* ast) - -> ExpressionResult; - - [[nodiscard]] auto operator()(BinaryExpressionAST* ast) -> ExpressionResult; - - [[nodiscard]] auto operator()(ConditionalExpressionAST* ast) - -> ExpressionResult; - - [[nodiscard]] auto operator()(YieldExpressionAST* ast) -> ExpressionResult; - - [[nodiscard]] auto operator()(ThrowExpressionAST* ast) -> ExpressionResult; - - [[nodiscard]] auto operator()(AssignmentExpressionAST* ast) - -> ExpressionResult; - - [[nodiscard]] auto operator()(CompoundAssignmentExpressionAST* ast) - -> ExpressionResult; - - [[nodiscard]] auto operator()(PackExpansionExpressionAST* ast) - -> ExpressionResult; - - [[nodiscard]] auto operator()(DesignatedInitializerClauseAST* ast) - -> ExpressionResult; - - [[nodiscard]] auto operator()(TypeTraitExpressionAST* ast) - -> ExpressionResult; - - [[nodiscard]] auto operator()(ConditionExpressionAST* ast) - -> ExpressionResult; - - [[nodiscard]] auto operator()(EqualInitializerAST* ast) -> ExpressionResult; - - [[nodiscard]] auto operator()(BracedInitListAST* ast) -> ExpressionResult; - - [[nodiscard]] auto operator()(ParenInitializerAST* ast) -> ExpressionResult; -}; - -struct ASTInterpreter::TemplateParameterVisitor { - ASTInterpreter& accept; - - [[nodiscard]] auto operator()(TemplateTypeParameterAST* ast) - -> TemplateParameterResult; - - [[nodiscard]] auto operator()(NonTypeTemplateParameterAST* ast) - -> TemplateParameterResult; - - [[nodiscard]] auto operator()(TypenameTypeParameterAST* ast) - -> TemplateParameterResult; - - [[nodiscard]] auto operator()(ConstraintTypeParameterAST* ast) - -> TemplateParameterResult; -}; - -struct ASTInterpreter::SpecifierVisitor { - ASTInterpreter& accept; - - [[nodiscard]] auto operator()(TypedefSpecifierAST* ast) -> SpecifierResult; - - [[nodiscard]] auto operator()(FriendSpecifierAST* ast) -> SpecifierResult; - - [[nodiscard]] auto operator()(ConstevalSpecifierAST* ast) -> SpecifierResult; - - [[nodiscard]] auto operator()(ConstinitSpecifierAST* ast) -> SpecifierResult; - - [[nodiscard]] auto operator()(ConstexprSpecifierAST* ast) -> SpecifierResult; - - [[nodiscard]] auto operator()(InlineSpecifierAST* ast) -> SpecifierResult; - - [[nodiscard]] auto operator()(NoreturnSpecifierAST* ast) -> SpecifierResult; - - [[nodiscard]] auto operator()(StaticSpecifierAST* ast) -> SpecifierResult; - - [[nodiscard]] auto operator()(ExternSpecifierAST* ast) -> SpecifierResult; - - [[nodiscard]] auto operator()(RegisterSpecifierAST* ast) -> SpecifierResult; - - [[nodiscard]] auto operator()(ThreadLocalSpecifierAST* ast) - -> SpecifierResult; - - [[nodiscard]] auto operator()(ThreadSpecifierAST* ast) -> SpecifierResult; - - [[nodiscard]] auto operator()(MutableSpecifierAST* ast) -> SpecifierResult; - - [[nodiscard]] auto operator()(VirtualSpecifierAST* ast) -> SpecifierResult; - - [[nodiscard]] auto operator()(ExplicitSpecifierAST* ast) -> SpecifierResult; - - [[nodiscard]] auto operator()(AutoTypeSpecifierAST* ast) -> SpecifierResult; - - [[nodiscard]] auto operator()(VoidTypeSpecifierAST* ast) -> SpecifierResult; - - [[nodiscard]] auto operator()(SizeTypeSpecifierAST* ast) -> SpecifierResult; - - [[nodiscard]] auto operator()(SignTypeSpecifierAST* ast) -> SpecifierResult; - - [[nodiscard]] auto operator()(BuiltinTypeSpecifierAST* ast) - -> SpecifierResult; - - [[nodiscard]] auto operator()(UnaryBuiltinTypeSpecifierAST* ast) - -> SpecifierResult; - - [[nodiscard]] auto operator()(BinaryBuiltinTypeSpecifierAST* ast) - -> SpecifierResult; - - [[nodiscard]] auto operator()(IntegralTypeSpecifierAST* ast) - -> SpecifierResult; - - [[nodiscard]] auto operator()(FloatingPointTypeSpecifierAST* ast) - -> SpecifierResult; - - [[nodiscard]] auto operator()(ComplexTypeSpecifierAST* ast) - -> SpecifierResult; - - [[nodiscard]] auto operator()(NamedTypeSpecifierAST* ast) -> SpecifierResult; - - [[nodiscard]] auto operator()(AtomicTypeSpecifierAST* ast) -> SpecifierResult; - - [[nodiscard]] auto operator()(UnderlyingTypeSpecifierAST* ast) - -> SpecifierResult; - - [[nodiscard]] auto operator()(ElaboratedTypeSpecifierAST* ast) - -> SpecifierResult; - - [[nodiscard]] auto operator()(DecltypeAutoSpecifierAST* ast) - -> SpecifierResult; - - [[nodiscard]] auto operator()(DecltypeSpecifierAST* ast) -> SpecifierResult; - - [[nodiscard]] auto operator()(PlaceholderTypeSpecifierAST* ast) - -> SpecifierResult; - - [[nodiscard]] auto operator()(ConstQualifierAST* ast) -> SpecifierResult; - - [[nodiscard]] auto operator()(VolatileQualifierAST* ast) -> SpecifierResult; - - [[nodiscard]] auto operator()(RestrictQualifierAST* ast) -> SpecifierResult; - - [[nodiscard]] auto operator()(AtomicQualifierAST* ast) -> SpecifierResult; - - [[nodiscard]] auto operator()(EnumSpecifierAST* ast) -> SpecifierResult; - - [[nodiscard]] auto operator()(ClassSpecifierAST* ast) -> SpecifierResult; - - [[nodiscard]] auto operator()(TypenameSpecifierAST* ast) -> SpecifierResult; - - [[nodiscard]] auto operator()(SplicerTypeSpecifierAST* ast) - -> SpecifierResult; -}; - -struct ASTInterpreter::PtrOperatorVisitor { - ASTInterpreter& accept; - - [[nodiscard]] auto operator()(PointerOperatorAST* ast) -> PtrOperatorResult; - - [[nodiscard]] auto operator()(ReferenceOperatorAST* ast) -> PtrOperatorResult; - - [[nodiscard]] auto operator()(PtrToMemberOperatorAST* ast) - -> PtrOperatorResult; -}; - -struct ASTInterpreter::CoreDeclaratorVisitor { - ASTInterpreter& accept; - - [[nodiscard]] auto operator()(BitfieldDeclaratorAST* ast) - -> CoreDeclaratorResult; - - [[nodiscard]] auto operator()(ParameterPackAST* ast) -> CoreDeclaratorResult; - - [[nodiscard]] auto operator()(IdDeclaratorAST* ast) -> CoreDeclaratorResult; - - [[nodiscard]] auto operator()(NestedDeclaratorAST* ast) - -> CoreDeclaratorResult; -}; - -struct ASTInterpreter::DeclaratorChunkVisitor { - ASTInterpreter& accept; - - [[nodiscard]] auto operator()(FunctionDeclaratorChunkAST* ast) - -> DeclaratorChunkResult; - - [[nodiscard]] auto operator()(ArrayDeclaratorChunkAST* ast) - -> DeclaratorChunkResult; -}; - -struct ASTInterpreter::UnqualifiedIdVisitor { - ASTInterpreter& accept; - - [[nodiscard]] auto operator()(NameIdAST* ast) -> UnqualifiedIdResult; - - [[nodiscard]] auto operator()(DestructorIdAST* ast) -> UnqualifiedIdResult; - - [[nodiscard]] auto operator()(DecltypeIdAST* ast) -> UnqualifiedIdResult; - - [[nodiscard]] auto operator()(OperatorFunctionIdAST* ast) - -> UnqualifiedIdResult; - - [[nodiscard]] auto operator()(LiteralOperatorIdAST* ast) - -> UnqualifiedIdResult; - - [[nodiscard]] auto operator()(ConversionFunctionIdAST* ast) - -> UnqualifiedIdResult; - - [[nodiscard]] auto operator()(SimpleTemplateIdAST* ast) - -> UnqualifiedIdResult; - - [[nodiscard]] auto operator()(LiteralOperatorTemplateIdAST* ast) - -> UnqualifiedIdResult; - - [[nodiscard]] auto operator()(OperatorFunctionTemplateIdAST* ast) - -> UnqualifiedIdResult; -}; - -struct ASTInterpreter::NestedNameSpecifierVisitor { - ASTInterpreter& accept; - - [[nodiscard]] auto operator()(GlobalNestedNameSpecifierAST* ast) - -> NestedNameSpecifierResult; - - [[nodiscard]] auto operator()(SimpleNestedNameSpecifierAST* ast) - -> NestedNameSpecifierResult; - - [[nodiscard]] auto operator()(DecltypeNestedNameSpecifierAST* ast) - -> NestedNameSpecifierResult; - - [[nodiscard]] auto operator()(TemplateNestedNameSpecifierAST* ast) - -> NestedNameSpecifierResult; -}; - -struct ASTInterpreter::FunctionBodyVisitor { - ASTInterpreter& accept; - - [[nodiscard]] auto operator()(DefaultFunctionBodyAST* ast) - -> FunctionBodyResult; - - [[nodiscard]] auto operator()(CompoundStatementFunctionBodyAST* ast) - -> FunctionBodyResult; - - [[nodiscard]] auto operator()(TryStatementFunctionBodyAST* ast) - -> FunctionBodyResult; - - [[nodiscard]] auto operator()(DeleteFunctionBodyAST* ast) - -> FunctionBodyResult; -}; - -struct ASTInterpreter::TemplateArgumentVisitor { - ASTInterpreter& accept; - - [[nodiscard]] auto operator()(TypeTemplateArgumentAST* ast) - -> TemplateArgumentResult; - - [[nodiscard]] auto operator()(ExpressionTemplateArgumentAST* ast) - -> TemplateArgumentResult; -}; - -struct ASTInterpreter::ExceptionSpecifierVisitor { - ASTInterpreter& accept; - - [[nodiscard]] auto operator()(ThrowExceptionSpecifierAST* ast) - -> ExceptionSpecifierResult; - - [[nodiscard]] auto operator()(NoexceptSpecifierAST* ast) - -> ExceptionSpecifierResult; -}; - -struct ASTInterpreter::RequirementVisitor { - ASTInterpreter& accept; - - [[nodiscard]] auto operator()(SimpleRequirementAST* ast) -> RequirementResult; - - [[nodiscard]] auto operator()(CompoundRequirementAST* ast) - -> RequirementResult; - - [[nodiscard]] auto operator()(TypeRequirementAST* ast) -> RequirementResult; - - [[nodiscard]] auto operator()(NestedRequirementAST* ast) -> RequirementResult; -}; - -struct ASTInterpreter::NewInitializerVisitor { - ASTInterpreter& accept; - - [[nodiscard]] auto operator()(NewParenInitializerAST* ast) - -> NewInitializerResult; - - [[nodiscard]] auto operator()(NewBracedInitializerAST* ast) - -> NewInitializerResult; -}; - -struct ASTInterpreter::MemInitializerVisitor { - ASTInterpreter& accept; - - [[nodiscard]] auto operator()(ParenMemInitializerAST* ast) - -> MemInitializerResult; - - [[nodiscard]] auto operator()(BracedMemInitializerAST* ast) - -> MemInitializerResult; -}; - -struct ASTInterpreter::LambdaCaptureVisitor { - ASTInterpreter& accept; - - [[nodiscard]] auto operator()(ThisLambdaCaptureAST* ast) - -> LambdaCaptureResult; - - [[nodiscard]] auto operator()(DerefThisLambdaCaptureAST* ast) - -> LambdaCaptureResult; - - [[nodiscard]] auto operator()(SimpleLambdaCaptureAST* ast) - -> LambdaCaptureResult; - - [[nodiscard]] auto operator()(RefLambdaCaptureAST* ast) - -> LambdaCaptureResult; - - [[nodiscard]] auto operator()(RefInitLambdaCaptureAST* ast) - -> LambdaCaptureResult; - - [[nodiscard]] auto operator()(InitLambdaCaptureAST* ast) - -> LambdaCaptureResult; -}; - -struct ASTInterpreter::ExceptionDeclarationVisitor { - ASTInterpreter& accept; - - [[nodiscard]] auto operator()(EllipsisExceptionDeclarationAST* ast) - -> ExceptionDeclarationResult; - - [[nodiscard]] auto operator()(TypeExceptionDeclarationAST* ast) - -> ExceptionDeclarationResult; -}; - -struct ASTInterpreter::AttributeSpecifierVisitor { - ASTInterpreter& accept; - - [[nodiscard]] auto operator()(CxxAttributeAST* ast) - -> AttributeSpecifierResult; - - [[nodiscard]] auto operator()(GccAttributeAST* ast) - -> AttributeSpecifierResult; - - [[nodiscard]] auto operator()(AlignasAttributeAST* ast) - -> AttributeSpecifierResult; - - [[nodiscard]] auto operator()(AlignasTypeAttributeAST* ast) - -> AttributeSpecifierResult; - - [[nodiscard]] auto operator()(AsmAttributeAST* ast) - -> AttributeSpecifierResult; -}; - -struct ASTInterpreter::AttributeTokenVisitor { - ASTInterpreter& accept; - - [[nodiscard]] auto operator()(ScopedAttributeTokenAST* ast) - -> AttributeTokenResult; - - [[nodiscard]] auto operator()(SimpleAttributeTokenAST* ast) - -> AttributeTokenResult; -}; - -auto ASTInterpreter::operator()(UnitAST* ast) -> UnitResult { - if (ast) return visit(UnitVisitor{*this}, ast); - return {}; -} - -auto ASTInterpreter::operator()(DeclarationAST* ast) -> DeclarationResult { - if (ast) return visit(DeclarationVisitor{*this}, ast); - return {}; -} - -auto ASTInterpreter::operator()(StatementAST* ast) -> StatementResult { - if (ast) return visit(StatementVisitor{*this}, ast); - return {}; -} - -auto ASTInterpreter::operator()(ExpressionAST* ast) -> ExpressionResult { - if (ast) return visit(ExpressionVisitor{*this}, ast); - return ExpressionResult{std::nullopt}; -} - -auto ASTInterpreter::operator()(TemplateParameterAST* ast) - -> TemplateParameterResult { - if (ast) return visit(TemplateParameterVisitor{*this}, ast); - return {}; -} - -auto ASTInterpreter::operator()(SpecifierAST* ast) -> SpecifierResult { - if (ast) return visit(SpecifierVisitor{*this}, ast); - return {}; -} - -auto ASTInterpreter::operator()(PtrOperatorAST* ast) -> PtrOperatorResult { - if (ast) return visit(PtrOperatorVisitor{*this}, ast); - return {}; -} - -auto ASTInterpreter::operator()(CoreDeclaratorAST* ast) - -> CoreDeclaratorResult { - if (ast) return visit(CoreDeclaratorVisitor{*this}, ast); - return {}; -} - -auto ASTInterpreter::operator()(DeclaratorChunkAST* ast) - -> DeclaratorChunkResult { - if (ast) return visit(DeclaratorChunkVisitor{*this}, ast); - return {}; -} - -auto ASTInterpreter::operator()(UnqualifiedIdAST* ast) -> UnqualifiedIdResult { - if (ast) return visit(UnqualifiedIdVisitor{*this}, ast); - return {}; -} - -auto ASTInterpreter::operator()(NestedNameSpecifierAST* ast) - -> NestedNameSpecifierResult { - if (ast) return visit(NestedNameSpecifierVisitor{*this}, ast); - return {}; -} - -auto ASTInterpreter::operator()(FunctionBodyAST* ast) -> FunctionBodyResult { - if (ast) return visit(FunctionBodyVisitor{*this}, ast); - return {}; -} - -auto ASTInterpreter::operator()(TemplateArgumentAST* ast) - -> TemplateArgumentResult { - if (ast) return visit(TemplateArgumentVisitor{*this}, ast); - return {}; -} - -auto ASTInterpreter::operator()(ExceptionSpecifierAST* ast) - -> ExceptionSpecifierResult { - if (ast) return visit(ExceptionSpecifierVisitor{*this}, ast); - return {}; -} - -auto ASTInterpreter::operator()(RequirementAST* ast) -> RequirementResult { - if (ast) return visit(RequirementVisitor{*this}, ast); - return {}; -} - -auto ASTInterpreter::operator()(NewInitializerAST* ast) - -> NewInitializerResult { - if (ast) return visit(NewInitializerVisitor{*this}, ast); - return {}; -} - -auto ASTInterpreter::operator()(MemInitializerAST* ast) - -> MemInitializerResult { - if (ast) return visit(MemInitializerVisitor{*this}, ast); - return {}; -} - -auto ASTInterpreter::operator()(LambdaCaptureAST* ast) -> LambdaCaptureResult { - if (ast) return visit(LambdaCaptureVisitor{*this}, ast); - return {}; -} - -auto ASTInterpreter::operator()(ExceptionDeclarationAST* ast) - -> ExceptionDeclarationResult { - if (ast) return visit(ExceptionDeclarationVisitor{*this}, ast); - return {}; -} - -auto ASTInterpreter::operator()(AttributeSpecifierAST* ast) - -> AttributeSpecifierResult { - if (ast) return visit(AttributeSpecifierVisitor{*this}, ast); - return {}; -} - -auto ASTInterpreter::operator()(AttributeTokenAST* ast) - -> AttributeTokenResult { - if (ast) return visit(AttributeTokenVisitor{*this}, ast); - return {}; -} - -auto ASTInterpreter::operator()(SplicerAST* ast) -> ExpressionResult { - if (!ast) return {}; - - auto expressionResult = operator()(ast->expression); - - return expressionResult; -} - -auto ASTInterpreter::operator()(GlobalModuleFragmentAST* ast) - -> GlobalModuleFragmentResult { - if (!ast) return {}; - - for (auto node : ListView{ast->declarationList}) { - auto value = operator()(node); - } - - return {}; -} - -auto ASTInterpreter::operator()(PrivateModuleFragmentAST* ast) - -> PrivateModuleFragmentResult { - if (!ast) return {}; - - for (auto node : ListView{ast->declarationList}) { - auto value = operator()(node); - } - - return {}; -} - -auto ASTInterpreter::operator()(ModuleDeclarationAST* ast) - -> ModuleDeclarationResult { - if (!ast) return {}; - - auto moduleNameResult = operator()(ast->moduleName); - auto modulePartitionResult = operator()(ast->modulePartition); - - for (auto node : ListView{ast->attributeList}) { - auto value = operator()(node); - } - - return {}; -} - -auto ASTInterpreter::operator()(ModuleNameAST* ast) -> ModuleNameResult { - if (!ast) return {}; - - auto moduleQualifierResult = operator()(ast->moduleQualifier); - - return {}; -} - -auto ASTInterpreter::operator()(ModuleQualifierAST* ast) - -> ModuleQualifierResult { - if (!ast) return {}; - - auto moduleQualifierResult = operator()(ast->moduleQualifier); - - return {}; -} - -auto ASTInterpreter::operator()(ModulePartitionAST* ast) - -> ModulePartitionResult { - if (!ast) return {}; - - auto moduleNameResult = operator()(ast->moduleName); - - return {}; -} - -auto ASTInterpreter::operator()(ImportNameAST* ast) -> ImportNameResult { - if (!ast) return {}; - - auto modulePartitionResult = operator()(ast->modulePartition); - auto moduleNameResult = operator()(ast->moduleName); - - return {}; -} - -auto ASTInterpreter::operator()(InitDeclaratorAST* ast) - -> InitDeclaratorResult { - if (!ast) return {}; - - auto declaratorResult = operator()(ast->declarator); - auto requiresClauseResult = operator()(ast->requiresClause); - auto initializerResult = operator()(ast->initializer); - - return {}; -} - -auto ASTInterpreter::operator()(DeclaratorAST* ast) -> DeclaratorResult { - if (!ast) return {}; - - for (auto node : ListView{ast->ptrOpList}) { - auto value = operator()(node); - } - - auto coreDeclaratorResult = operator()(ast->coreDeclarator); - - for (auto node : ListView{ast->declaratorChunkList}) { - auto value = operator()(node); - } - - return {}; -} - -auto ASTInterpreter::operator()(UsingDeclaratorAST* ast) - -> UsingDeclaratorResult { - if (!ast) return {}; - - auto nestedNameSpecifierResult = operator()(ast->nestedNameSpecifier); - auto unqualifiedIdResult = operator()(ast->unqualifiedId); - - return {}; -} - -auto ASTInterpreter::operator()(EnumeratorAST* ast) -> EnumeratorResult { - if (!ast) return {}; - - for (auto node : ListView{ast->attributeList}) { - auto value = operator()(node); - } - - auto expressionResult = operator()(ast->expression); - - return {}; -} - -auto ASTInterpreter::operator()(TypeIdAST* ast) -> TypeIdResult { - if (!ast) return {}; - - for (auto node : ListView{ast->typeSpecifierList}) { - auto value = operator()(node); - } - - auto declaratorResult = operator()(ast->declarator); - - return {}; -} - -auto ASTInterpreter::operator()(HandlerAST* ast) -> HandlerResult { - if (!ast) return {}; - - auto exceptionDeclarationResult = operator()(ast->exceptionDeclaration); - auto statementResult = operator()(ast->statement); - - return {}; -} - -auto ASTInterpreter::operator()(BaseSpecifierAST* ast) -> BaseSpecifierResult { - if (!ast) return {}; - - for (auto node : ListView{ast->attributeList}) { - auto value = operator()(node); - } - - auto nestedNameSpecifierResult = operator()(ast->nestedNameSpecifier); - auto unqualifiedIdResult = operator()(ast->unqualifiedId); - - return {}; -} - -auto ASTInterpreter::operator()(RequiresClauseAST* ast) - -> RequiresClauseResult { - if (!ast) return {}; - - auto expressionResult = operator()(ast->expression); - - return {}; -} - -auto ASTInterpreter::operator()(ParameterDeclarationClauseAST* ast) - -> ParameterDeclarationClauseResult { - if (!ast) return {}; - - for (auto node : ListView{ast->parameterDeclarationList}) { - auto value = operator()(node); - } - - return {}; -} - -auto ASTInterpreter::operator()(TrailingReturnTypeAST* ast) - -> TrailingReturnTypeResult { - if (!ast) return {}; - - auto typeIdResult = operator()(ast->typeId); - - return {}; -} - -auto ASTInterpreter::operator()(LambdaSpecifierAST* ast) - -> LambdaSpecifierResult { - if (!ast) return {}; - - return {}; -} - -auto ASTInterpreter::operator()(TypeConstraintAST* ast) - -> TypeConstraintResult { - if (!ast) return {}; - - auto nestedNameSpecifierResult = operator()(ast->nestedNameSpecifier); - - for (auto node : ListView{ast->templateArgumentList}) { - auto value = operator()(node); - } - - return {}; -} - -auto ASTInterpreter::operator()(AttributeArgumentClauseAST* ast) - -> AttributeArgumentClauseResult { - if (!ast) return {}; - - return {}; -} - -auto ASTInterpreter::operator()(AttributeAST* ast) -> AttributeResult { - if (!ast) return {}; - - auto attributeTokenResult = operator()(ast->attributeToken); - auto attributeArgumentClauseResult = operator()(ast->attributeArgumentClause); - - return {}; -} - -auto ASTInterpreter::operator()(AttributeUsingPrefixAST* ast) - -> AttributeUsingPrefixResult { - if (!ast) return {}; - - return {}; -} - -auto ASTInterpreter::operator()(NewPlacementAST* ast) -> NewPlacementResult { - if (!ast) return {}; - - for (auto node : ListView{ast->expressionList}) { - auto value = operator()(node); - } - - return {}; -} - -auto ASTInterpreter::operator()(NestedNamespaceSpecifierAST* ast) - -> NestedNamespaceSpecifierResult { - if (!ast) return {}; - - return {}; -} - -auto ASTInterpreter::operator()(AsmOperandAST* ast) -> DeclarationResult { - auto expressionResult = operator()(ast->expression); - - return {}; -} - -auto ASTInterpreter::operator()(AsmQualifierAST* ast) -> DeclarationResult { - return {}; -} - -auto ASTInterpreter::operator()(AsmClobberAST* ast) -> DeclarationResult { - return {}; -} - -auto ASTInterpreter::operator()(AsmGotoLabelAST* ast) -> DeclarationResult { - return {}; -} - -auto ASTInterpreter::UnitVisitor::operator()(TranslationUnitAST* ast) - -> UnitResult { - for (auto node : ListView{ast->declarationList}) { - auto value = accept(node); - } - - return {}; -} - -auto ASTInterpreter::UnitVisitor::operator()(ModuleUnitAST* ast) -> UnitResult { - auto globalModuleFragmentResult = accept(ast->globalModuleFragment); - auto moduleDeclarationResult = accept(ast->moduleDeclaration); - - for (auto node : ListView{ast->declarationList}) { - auto value = accept(node); - } - - auto privateModuleFragmentResult = accept(ast->privateModuleFragment); - - return {}; -} - -auto ASTInterpreter::DeclarationVisitor::operator()(SimpleDeclarationAST* ast) - -> DeclarationResult { - for (auto node : ListView{ast->attributeList}) { - auto value = accept(node); - } - - for (auto node : ListView{ast->declSpecifierList}) { - auto value = accept(node); - } - - for (auto node : ListView{ast->initDeclaratorList}) { - auto value = accept(node); - } - - auto requiresClauseResult = accept(ast->requiresClause); - - return {}; -} - -auto ASTInterpreter::DeclarationVisitor::operator()(AsmDeclarationAST* ast) - -> DeclarationResult { - for (auto node : ListView{ast->attributeList}) { - auto value = accept(node); - } - - for (auto node : ListView{ast->asmQualifierList}) { - auto value = accept(node); - } - - for (auto node : ListView{ast->outputOperandList}) { - auto value = accept(node); - } - - for (auto node : ListView{ast->inputOperandList}) { - auto value = accept(node); - } - - for (auto node : ListView{ast->clobberList}) { - auto value = accept(node); - } - - for (auto node : ListView{ast->gotoLabelList}) { - auto value = accept(node); - } - - return {}; -} - -auto ASTInterpreter::DeclarationVisitor::operator()( - NamespaceAliasDefinitionAST* ast) -> DeclarationResult { - auto nestedNameSpecifierResult = accept(ast->nestedNameSpecifier); - auto unqualifiedIdResult = accept(ast->unqualifiedId); - - return {}; -} - -auto ASTInterpreter::DeclarationVisitor::operator()(UsingDeclarationAST* ast) - -> DeclarationResult { - for (auto node : ListView{ast->usingDeclaratorList}) { - auto value = accept(node); - } - - return {}; -} - -auto ASTInterpreter::DeclarationVisitor::operator()( - UsingEnumDeclarationAST* ast) -> DeclarationResult { - auto enumTypeSpecifierResult = accept(ast->enumTypeSpecifier); - - return {}; -} - -auto ASTInterpreter::DeclarationVisitor::operator()(UsingDirectiveAST* ast) - -> DeclarationResult { - for (auto node : ListView{ast->attributeList}) { - auto value = accept(node); - } - - auto nestedNameSpecifierResult = accept(ast->nestedNameSpecifier); - auto unqualifiedIdResult = accept(ast->unqualifiedId); - - return {}; -} - -auto ASTInterpreter::DeclarationVisitor::operator()( - StaticAssertDeclarationAST* ast) -> DeclarationResult { - auto expressionResult = accept(ast->expression); - - return {}; -} - -auto ASTInterpreter::DeclarationVisitor::operator()(AliasDeclarationAST* ast) - -> DeclarationResult { - for (auto node : ListView{ast->attributeList}) { - auto value = accept(node); - } - - for (auto node : ListView{ast->gnuAttributeList}) { - auto value = accept(node); - } - - auto typeIdResult = accept(ast->typeId); - - return {}; -} - -auto ASTInterpreter::DeclarationVisitor::operator()( - OpaqueEnumDeclarationAST* ast) -> DeclarationResult { - for (auto node : ListView{ast->attributeList}) { - auto value = accept(node); - } - - auto nestedNameSpecifierResult = accept(ast->nestedNameSpecifier); - auto unqualifiedIdResult = accept(ast->unqualifiedId); - - for (auto node : ListView{ast->typeSpecifierList}) { - auto value = accept(node); - } - - return {}; -} - -auto ASTInterpreter::DeclarationVisitor::operator()(FunctionDefinitionAST* ast) - -> DeclarationResult { - for (auto node : ListView{ast->attributeList}) { - auto value = accept(node); - } - - for (auto node : ListView{ast->declSpecifierList}) { - auto value = accept(node); - } - - auto declaratorResult = accept(ast->declarator); - auto requiresClauseResult = accept(ast->requiresClause); - auto functionBodyResult = accept(ast->functionBody); - - return {}; -} - -auto ASTInterpreter::DeclarationVisitor::operator()(TemplateDeclarationAST* ast) - -> DeclarationResult { - for (auto node : ListView{ast->templateParameterList}) { - auto value = accept(node); - } - - auto requiresClauseResult = accept(ast->requiresClause); - auto declarationResult = accept(ast->declaration); - - return {}; -} - -auto ASTInterpreter::DeclarationVisitor::operator()(ConceptDefinitionAST* ast) - -> DeclarationResult { - auto expressionResult = accept(ast->expression); - - return {}; -} - -auto ASTInterpreter::DeclarationVisitor::operator()(DeductionGuideAST* ast) - -> DeclarationResult { - auto explicitSpecifierResult = accept(ast->explicitSpecifier); - auto parameterDeclarationClauseResult = - accept(ast->parameterDeclarationClause); - auto templateIdResult = accept(ast->templateId); - - return {}; -} - -auto ASTInterpreter::DeclarationVisitor::operator()( - ExplicitInstantiationAST* ast) -> DeclarationResult { - auto declarationResult = accept(ast->declaration); - - return {}; -} - -auto ASTInterpreter::DeclarationVisitor::operator()(ExportDeclarationAST* ast) - -> DeclarationResult { - auto declarationResult = accept(ast->declaration); - - return {}; -} - -auto ASTInterpreter::DeclarationVisitor::operator()( - ExportCompoundDeclarationAST* ast) -> DeclarationResult { - for (auto node : ListView{ast->declarationList}) { - auto value = accept(node); - } - - return {}; -} - -auto ASTInterpreter::DeclarationVisitor::operator()( - LinkageSpecificationAST* ast) -> DeclarationResult { - for (auto node : ListView{ast->declarationList}) { - auto value = accept(node); - } - - return {}; -} - -auto ASTInterpreter::DeclarationVisitor::operator()(NamespaceDefinitionAST* ast) - -> DeclarationResult { - for (auto node : ListView{ast->attributeList}) { - auto value = accept(node); - } - - for (auto node : ListView{ast->nestedNamespaceSpecifierList}) { - auto value = accept(node); - } - - for (auto node : ListView{ast->extraAttributeList}) { - auto value = accept(node); - } - - for (auto node : ListView{ast->declarationList}) { - auto value = accept(node); - } - - return {}; -} - -auto ASTInterpreter::DeclarationVisitor::operator()(EmptyDeclarationAST* ast) - -> DeclarationResult { - return {}; -} - -auto ASTInterpreter::DeclarationVisitor::operator()( - AttributeDeclarationAST* ast) -> DeclarationResult { - for (auto node : ListView{ast->attributeList}) { - auto value = accept(node); - } - - return {}; -} - -auto ASTInterpreter::DeclarationVisitor::operator()( - ModuleImportDeclarationAST* ast) -> DeclarationResult { - auto importNameResult = accept(ast->importName); - - for (auto node : ListView{ast->attributeList}) { - auto value = accept(node); - } - - return {}; -} - -auto ASTInterpreter::DeclarationVisitor::operator()( - ParameterDeclarationAST* ast) -> DeclarationResult { - for (auto node : ListView{ast->attributeList}) { - auto value = accept(node); - } - - for (auto node : ListView{ast->typeSpecifierList}) { - auto value = accept(node); - } - - auto declaratorResult = accept(ast->declarator); - auto expressionResult = accept(ast->expression); - - return {}; -} - -auto ASTInterpreter::DeclarationVisitor::operator()(AccessDeclarationAST* ast) - -> DeclarationResult { - return {}; -} - -auto ASTInterpreter::DeclarationVisitor::operator()(ForRangeDeclarationAST* ast) - -> DeclarationResult { - return {}; -} - -auto ASTInterpreter::DeclarationVisitor::operator()( - StructuredBindingDeclarationAST* ast) -> DeclarationResult { - for (auto node : ListView{ast->attributeList}) { - auto value = accept(node); - } - - for (auto node : ListView{ast->declSpecifierList}) { - auto value = accept(node); - } - - for (auto node : ListView{ast->bindingList}) { - auto value = accept(node); - } - - auto initializerResult = accept(ast->initializer); - - return {}; -} - -auto ASTInterpreter::StatementVisitor::operator()(LabeledStatementAST* ast) - -> StatementResult { - return {}; -} - -auto ASTInterpreter::StatementVisitor::operator()(CaseStatementAST* ast) - -> StatementResult { - auto expressionResult = accept(ast->expression); - - return {}; -} - -auto ASTInterpreter::StatementVisitor::operator()(DefaultStatementAST* ast) - -> StatementResult { - return {}; -} - -auto ASTInterpreter::StatementVisitor::operator()(ExpressionStatementAST* ast) - -> StatementResult { - auto expressionResult = accept(ast->expression); - - return {}; -} - -auto ASTInterpreter::StatementVisitor::operator()(CompoundStatementAST* ast) - -> StatementResult { - for (auto node : ListView{ast->statementList}) { - auto value = accept(node); - } - - return {}; -} - -auto ASTInterpreter::StatementVisitor::operator()(IfStatementAST* ast) - -> StatementResult { - auto initializerResult = accept(ast->initializer); - auto conditionResult = accept(ast->condition); - auto statementResult = accept(ast->statement); - auto elseStatementResult = accept(ast->elseStatement); - - return {}; -} - -auto ASTInterpreter::StatementVisitor::operator()(ConstevalIfStatementAST* ast) - -> StatementResult { - auto statementResult = accept(ast->statement); - auto elseStatementResult = accept(ast->elseStatement); - - return {}; -} - -auto ASTInterpreter::StatementVisitor::operator()(SwitchStatementAST* ast) - -> StatementResult { - auto initializerResult = accept(ast->initializer); - auto conditionResult = accept(ast->condition); - auto statementResult = accept(ast->statement); - - return {}; -} - -auto ASTInterpreter::StatementVisitor::operator()(WhileStatementAST* ast) - -> StatementResult { - auto conditionResult = accept(ast->condition); - auto statementResult = accept(ast->statement); - - return {}; -} - -auto ASTInterpreter::StatementVisitor::operator()(DoStatementAST* ast) - -> StatementResult { - auto statementResult = accept(ast->statement); - auto expressionResult = accept(ast->expression); - - return {}; -} - -auto ASTInterpreter::StatementVisitor::operator()(ForRangeStatementAST* ast) - -> StatementResult { - auto initializerResult = accept(ast->initializer); - auto rangeDeclarationResult = accept(ast->rangeDeclaration); - auto rangeInitializerResult = accept(ast->rangeInitializer); - auto statementResult = accept(ast->statement); - - return {}; -} - -auto ASTInterpreter::StatementVisitor::operator()(ForStatementAST* ast) - -> StatementResult { - auto initializerResult = accept(ast->initializer); - auto conditionResult = accept(ast->condition); - auto expressionResult = accept(ast->expression); - auto statementResult = accept(ast->statement); - - return {}; -} - -auto ASTInterpreter::StatementVisitor::operator()(BreakStatementAST* ast) - -> StatementResult { - return {}; -} - -auto ASTInterpreter::StatementVisitor::operator()(ContinueStatementAST* ast) - -> StatementResult { - return {}; -} - -auto ASTInterpreter::StatementVisitor::operator()(ReturnStatementAST* ast) - -> StatementResult { - auto expressionResult = accept(ast->expression); - - return {}; -} - -auto ASTInterpreter::StatementVisitor::operator()( - CoroutineReturnStatementAST* ast) -> StatementResult { - auto expressionResult = accept(ast->expression); - - return {}; -} - -auto ASTInterpreter::StatementVisitor::operator()(GotoStatementAST* ast) - -> StatementResult { - return {}; -} - -auto ASTInterpreter::StatementVisitor::operator()(DeclarationStatementAST* ast) - -> StatementResult { - auto declarationResult = accept(ast->declaration); - - return {}; -} - -auto ASTInterpreter::StatementVisitor::operator()(TryBlockStatementAST* ast) - -> StatementResult { - auto statementResult = accept(ast->statement); - - for (auto node : ListView{ast->handlerList}) { - auto value = accept(node); - } - - return {}; -} - -auto ASTInterpreter::ExpressionVisitor::operator()( - CharLiteralExpressionAST* ast) -> ExpressionResult { - return ConstValue(ast->literal->charValue()); -} - -auto ASTInterpreter::ExpressionVisitor::operator()( - BoolLiteralExpressionAST* ast) -> ExpressionResult { - return ConstValue(ast->isTrue); -} - -auto ASTInterpreter::ExpressionVisitor::operator()(IntLiteralExpressionAST* ast) - -> ExpressionResult { - const auto value = static_cast(ast->literal->integerValue()); - return ExpressionResult{std::bit_cast(value)}; -} - -auto ASTInterpreter::ExpressionVisitor::operator()( - FloatLiteralExpressionAST* ast) -> ExpressionResult { - return ConstValue(ast->literal->floatValue()); -} - -auto ASTInterpreter::ExpressionVisitor::operator()( - NullptrLiteralExpressionAST* ast) -> ExpressionResult { - return ConstValue{std::intmax_t(0)}; -} - -auto ASTInterpreter::ExpressionVisitor::operator()( - StringLiteralExpressionAST* ast) -> ExpressionResult { - return ConstValue(ast->literal); -} - -auto ASTInterpreter::ExpressionVisitor::operator()( - UserDefinedStringLiteralExpressionAST* ast) -> ExpressionResult { - return ConstValue(ast->literal); -} - -auto ASTInterpreter::ExpressionVisitor::operator()( - ObjectLiteralExpressionAST* ast) -> ExpressionResult { - return std::nullopt; -} - -auto ASTInterpreter::ExpressionVisitor::operator()(ThisExpressionAST* ast) - -> ExpressionResult { - return std::nullopt; -} - -auto ASTInterpreter::ExpressionVisitor::operator()( - GenericSelectionExpressionAST* ast) -> ExpressionResult { - if (ast->matchedAssocIndex == -1) return std::nullopt; - - GenericAssociationAST* assoc = nullptr; - int index = 0; - for (auto assocNode : ListView{ast->genericAssociationList}) { - if (index == ast->matchedAssocIndex) { - assoc = assocNode; - break; - } - ++index; - } - - if (auto def = ast_cast(assoc)) { - return accept(def->expression); - } - - if (auto entry = ast_cast(assoc)) { - return accept(entry->expression); - } - - return std::nullopt; -} - -auto ASTInterpreter::ExpressionVisitor::operator()(NestedExpressionAST* ast) - -> ExpressionResult { - if (ast->expression) { - return evaluate(ast->expression); - } - return std::nullopt; -} - -auto ASTInterpreter::ExpressionVisitor::operator()( - NestedStatementExpressionAST* ast) -> ExpressionResult { - return std::nullopt; -} - -auto ASTInterpreter::ExpressionVisitor::operator()(IdExpressionAST* ast) - -> ExpressionResult { - auto nestedNameSpecifierResult = accept(ast->nestedNameSpecifier); - auto unqualifiedIdResult = accept(ast->unqualifiedId); - - if (auto enumerator = symbol_cast(ast->symbol)) { - return enumerator->value(); - } - - if (auto var = symbol_cast(ast->symbol)) { - return var->constValue(); - } - - return std::nullopt; -} - -auto ASTInterpreter::ExpressionVisitor::operator()(LambdaExpressionAST* ast) - -> ExpressionResult { - for (auto node : ListView{ast->captureList}) { - auto value = accept(node); - } - - for (auto node : ListView{ast->templateParameterList}) { - auto value = accept(node); - } - - auto templateRequiresClauseResult = accept(ast->templateRequiresClause); - auto parameterDeclarationClauseResult = - accept(ast->parameterDeclarationClause); - - for (auto node : ListView{ast->gnuAtributeList}) { - auto value = accept(node); - } - - for (auto node : ListView{ast->lambdaSpecifierList}) { - auto value = accept(node); - } - - auto exceptionSpecifierResult = accept(ast->exceptionSpecifier); - - for (auto node : ListView{ast->attributeList}) { - auto value = accept(node); - } - - auto trailingReturnTypeResult = accept(ast->trailingReturnType); - auto requiresClauseResult = accept(ast->requiresClause); - auto statementResult = accept(ast->statement); - - return ExpressionResult{std::nullopt}; -} - -auto ASTInterpreter::ExpressionVisitor::operator()(FoldExpressionAST* ast) - -> ExpressionResult { - auto leftExpressionResult = accept(ast->leftExpression); - auto rightExpressionResult = accept(ast->rightExpression); - - return ExpressionResult{std::nullopt}; -} - -auto ASTInterpreter::ExpressionVisitor::operator()(RightFoldExpressionAST* ast) - -> ExpressionResult { - auto expressionResult = accept(ast->expression); - - return ExpressionResult{std::nullopt}; -} - -auto ASTInterpreter::ExpressionVisitor::operator()(LeftFoldExpressionAST* ast) - -> ExpressionResult { - auto expressionResult = accept(ast->expression); - - return ExpressionResult{std::nullopt}; -} - -auto ASTInterpreter::ExpressionVisitor::operator()(RequiresExpressionAST* ast) - -> ExpressionResult { - auto parameterDeclarationClauseResult = - accept(ast->parameterDeclarationClause); - - for (auto node : ListView{ast->requirementList}) { - auto value = accept(node); - } - - return ExpressionResult{std::nullopt}; -} - -auto ASTInterpreter::ExpressionVisitor::operator()(VaArgExpressionAST* ast) - -> ExpressionResult { - auto expressionResult = accept(ast->expression); - auto typeIdResult = accept(ast->typeId); - - return ExpressionResult{std::nullopt}; -} - -auto ASTInterpreter::ExpressionVisitor::operator()(SubscriptExpressionAST* ast) - -> ExpressionResult { - auto baseExpressionResult = accept(ast->baseExpression); - auto indexExpressionResult = accept(ast->indexExpression); - - return ExpressionResult{std::nullopt}; -} - -auto ASTInterpreter::ExpressionVisitor::operator()(CallExpressionAST* ast) - -> ExpressionResult { - auto baseExpressionResult = accept(ast->baseExpression); - - for (auto node : ListView{ast->expressionList}) { - auto value = accept(node); - } - - return ExpressionResult{std::nullopt}; -} - -auto ASTInterpreter::ExpressionVisitor::operator()(TypeConstructionAST* ast) - -> ExpressionResult { - auto typeSpecifierResult = accept(ast->typeSpecifier); - - for (auto node : ListView{ast->expressionList}) { - auto value = accept(node); - } - - return ExpressionResult{std::nullopt}; -} - -auto ASTInterpreter::ExpressionVisitor::operator()( - BracedTypeConstructionAST* ast) -> ExpressionResult { - auto typeSpecifierResult = accept(ast->typeSpecifier); - auto bracedInitListResult = accept(ast->bracedInitList); - - return ExpressionResult{std::nullopt}; -} - -auto ASTInterpreter::ExpressionVisitor::operator()( - SpliceMemberExpressionAST* ast) -> ExpressionResult { - auto baseExpressionResult = accept(ast->baseExpression); - auto splicerResult = accept(ast->splicer); - - return ExpressionResult{std::nullopt}; -} - -auto ASTInterpreter::ExpressionVisitor::operator()(MemberExpressionAST* ast) - -> ExpressionResult { - auto baseExpressionResult = accept(ast->baseExpression); - auto nestedNameSpecifierResult = accept(ast->nestedNameSpecifier); - auto unqualifiedIdResult = accept(ast->unqualifiedId); - - return ExpressionResult{std::nullopt}; -} - -auto ASTInterpreter::ExpressionVisitor::operator()(PostIncrExpressionAST* ast) - -> ExpressionResult { - auto baseExpressionResult = accept(ast->baseExpression); - - return ExpressionResult{std::nullopt}; -} - -auto ASTInterpreter::ExpressionVisitor::operator()(CppCastExpressionAST* ast) - -> ExpressionResult { - auto typeIdResult = accept(ast->typeId); - auto expressionResult = accept(ast->expression); - - return ExpressionResult{std::nullopt}; -} - -auto ASTInterpreter::ExpressionVisitor::operator()( - BuiltinBitCastExpressionAST* ast) -> ExpressionResult { - auto typeIdResult = accept(ast->typeId); - auto expressionResult = accept(ast->expression); - - return ExpressionResult{std::nullopt}; -} - -auto ASTInterpreter::ExpressionVisitor::operator()( - BuiltinOffsetofExpressionAST* ast) -> ExpressionResult { - auto typeIdResult = accept(ast->typeId); - - if (ast->symbol) return ast->symbol->offset(); - - return std::nullopt; -} - -auto ASTInterpreter::ExpressionVisitor::operator()(TypeidExpressionAST* ast) - -> ExpressionResult { - auto expressionResult = accept(ast->expression); - - return ExpressionResult{std::nullopt}; -} - -auto ASTInterpreter::ExpressionVisitor::operator()( - TypeidOfTypeExpressionAST* ast) -> ExpressionResult { - auto typeIdResult = accept(ast->typeId); - - return ExpressionResult{std::nullopt}; -} - -auto ASTInterpreter::ExpressionVisitor::operator()(SpliceExpressionAST* ast) - -> ExpressionResult { - auto splicerResult = accept(ast->splicer); - if (!splicerResult.has_value()) return std::nullopt; - - auto metaPtr = std::get_if>(&splicerResult.value()); - if (!metaPtr) return std::nullopt; - - auto meta = *metaPtr; - - auto constExprPtr = std::get_if(&meta->value); - if (!constExprPtr) return std::nullopt; - - return constExprPtr->value; -} - -auto ASTInterpreter::ExpressionVisitor::operator()( - GlobalScopeReflectExpressionAST* ast) -> ExpressionResult { - return ExpressionResult{std::nullopt}; -} - -auto ASTInterpreter::ExpressionVisitor::operator()( - NamespaceReflectExpressionAST* ast) -> ExpressionResult { - return ExpressionResult{std::nullopt}; -} - -auto ASTInterpreter::ExpressionVisitor::operator()( - TypeIdReflectExpressionAST* ast) -> ExpressionResult { - if (!ast->typeId) return std::nullopt; - if (!ast->typeId->type) return std::nullopt; - - auto meta = std::make_shared(ast->typeId->type); - - return ConstValue{meta}; -} - -auto ASTInterpreter::ExpressionVisitor::operator()(ReflectExpressionAST* ast) - -> ExpressionResult { - auto expressionResult = accept(ast->expression); - - if (expressionResult.has_value()) { - auto meta = std::make_shared(Meta::ConstExpr{ - .expression = ast->expression, .value = expressionResult.value()}); - return meta; - } - - return ExpressionResult{std::nullopt}; -} - -auto ASTInterpreter::ExpressionVisitor::operator()( - LabelAddressExpressionAST* ast) -> ExpressionResult { - return ExpressionResult{std::nullopt}; -} - -auto ASTInterpreter::ExpressionVisitor::operator()(UnaryExpressionAST* ast) - -> ExpressionResult { - auto expressionResult = accept(ast->expression); - - return ExpressionResult{std::nullopt}; -} - -auto ASTInterpreter::ExpressionVisitor::operator()(AwaitExpressionAST* ast) - -> ExpressionResult { - auto expressionResult = accept(ast->expression); - - return ExpressionResult{std::nullopt}; -} - -auto ASTInterpreter::ExpressionVisitor::operator()(SizeofExpressionAST* ast) - -> ExpressionResult { - if (!ast->expression || !ast->expression->type) return std::nullopt; - auto size = memoryLayout()->sizeOf(ast->expression->type); - if (!size.has_value()) return std::nullopt; - return ExpressionResult( - std::bit_cast(static_cast(*size))); -} - -auto ASTInterpreter::ExpressionVisitor::operator()(SizeofTypeExpressionAST* ast) - -> ExpressionResult { - if (!ast->typeId || !ast->typeId->type) return std::nullopt; - auto size = memoryLayout()->sizeOf(ast->typeId->type); - if (!size.has_value()) return std::nullopt; - return ExpressionResult( - std::bit_cast(static_cast(*size))); -} - -auto ASTInterpreter::ExpressionVisitor::operator()(SizeofPackExpressionAST* ast) - -> ExpressionResult { - return ExpressionResult{std::nullopt}; -} - -auto ASTInterpreter::ExpressionVisitor::operator()( - AlignofTypeExpressionAST* ast) -> ExpressionResult { - if (!ast->typeId || !ast->typeId->type) return std::nullopt; - auto size = memoryLayout()->alignmentOf(ast->typeId->type); - if (!size.has_value()) return std::nullopt; - return ExpressionResult( - std::bit_cast(static_cast(*size))); -} - -auto ASTInterpreter::ExpressionVisitor::operator()(AlignofExpressionAST* ast) - -> ExpressionResult { - auto expressionResult = accept(ast->expression); - - if (!ast->expression || !ast->expression->type) return std::nullopt; - auto size = memoryLayout()->alignmentOf(ast->expression->type); - if (!size.has_value()) return std::nullopt; - return ExpressionResult( - std::bit_cast(static_cast(*size))); -} - -auto ASTInterpreter::ExpressionVisitor::operator()(NoexceptExpressionAST* ast) - -> ExpressionResult { - auto expressionResult = accept(ast->expression); - - return ExpressionResult{std::nullopt}; -} - -auto ASTInterpreter::ExpressionVisitor::operator()(NewExpressionAST* ast) - -> ExpressionResult { - auto newPlacementResult = accept(ast->newPlacement); - - for (auto node : ListView{ast->typeSpecifierList}) { - auto value = accept(node); - } - - auto declaratorResult = accept(ast->declarator); - auto newInitalizerResult = accept(ast->newInitalizer); - - return ExpressionResult{std::nullopt}; -} - -auto ASTInterpreter::ExpressionVisitor::operator()(DeleteExpressionAST* ast) - -> ExpressionResult { - auto expressionResult = accept(ast->expression); - - return ExpressionResult{std::nullopt}; -} - -auto ASTInterpreter::ExpressionVisitor::operator()(CastExpressionAST* ast) - -> ExpressionResult { - auto typeIdResult = accept(ast->typeId); - auto expressionResult = accept(ast->expression); - - return ExpressionResult{std::nullopt}; -} - -auto ASTInterpreter::ExpressionVisitor::operator()( - ImplicitCastExpressionAST* ast) -> ExpressionResult { - if (!ast->type) return std::nullopt; - - auto value = evaluate(ast->expression); - if (!value.has_value()) return std::nullopt; - - switch (ast->type->kind()) { - case TypeKind::kBool: { - auto result = accept.toBool(*value); - if (!result.has_value()) return std::nullopt; - return result.value(); - } - - case TypeKind::kFloat: { - auto result = accept.toFloat(*value); - if (!result.has_value()) return std::nullopt; - return result.value(); - } - - case TypeKind::kDouble: { - auto result = accept.toDouble(*value); - if (!result.has_value()) return std::nullopt; - return result.value(); - } - - case TypeKind::kLongDouble: { - auto result = accept.toLongDouble(*value); - if (!result.has_value()) return std::nullopt; - return result.value(); - } - - default: - if (control()->is_integral_or_unscoped_enum(ast->type)) { - if (control()->is_unsigned(ast->type)) { - auto result = accept.toUInt(*value); - if (!result.has_value()) return std::nullopt; - return ConstValue{std::bit_cast(result.value())}; - } - - auto result = accept.toInt(*value); - if (!result.has_value()) return std::nullopt; - return result.value(); - } - - return value; - } // switch - - return std::nullopt; -} - -auto ASTInterpreter::ExpressionVisitor::operator()(BinaryExpressionAST* ast) - -> ExpressionResult { - if (!ast->type) return std::nullopt; - - auto left = evaluate(ast->leftExpression); - if (!left.has_value()) return std::nullopt; - - auto right = evaluate(ast->rightExpression); - if (!right.has_value()) return std::nullopt; - - switch (ast->op) { - case TokenKind::T_DOT_STAR: - break; - - case TokenKind::T_MINUS_GREATER_STAR: - break; - - case TokenKind::T_STAR: - return star_op(ast, left, right); - - case TokenKind::T_SLASH: - return slash_op(ast, left, right); - - case TokenKind::T_PERCENT: - return percent_op(ast, left, right); - - case TokenKind::T_PLUS: - return plus_op(ast, left, right); - - case TokenKind::T_MINUS: - return minus_op(ast, left, right); - - case TokenKind::T_LESS_LESS: - return less_less_op(ast, left, right); - - case TokenKind::T_GREATER_GREATER: - return greater_greater_op(ast, left, right); - - case TokenKind::T_LESS_EQUAL_GREATER: - return less_equal_greater_op(ast, left, right); - - case TokenKind::T_LESS_EQUAL: - return less_equal_op(ast, left, right); - - case TokenKind::T_GREATER_EQUAL: - return greater_equal_op(ast, left, right); - - case TokenKind::T_LESS: - return less_op(ast, left, right); - - case TokenKind::T_GREATER: - return greater_op(ast, left, right); - - case TokenKind::T_EQUAL_EQUAL: - return equal_equal_op(ast, left, right); - - case TokenKind::T_EXCLAIM_EQUAL: - return exclaim_equal_op(ast, left, right); - - case TokenKind::T_AMP: - return amp_op(ast, left, right); - - case TokenKind::T_CARET: - return caret_op(ast, left, right); - - case TokenKind::T_BAR: - return bar_op(ast, left, right); - - case TokenKind::T_AMP_AMP: - return amp_amp_op(ast, left, right); - - case TokenKind::T_BAR_BAR: - return bar_bar_op(ast, left, right); - - case TokenKind::T_COMMA: - return comma_op(ast, left, right); - - default: - unit()->warning(ast->opLoc, "invalid binary expression"); - break; - } // switch - - return std::nullopt; -} - -auto ASTInterpreter::ExpressionVisitor::operator()( - ConditionalExpressionAST* ast) -> ExpressionResult { - auto conditionResult = accept(ast->condition); - - if (!conditionResult.has_value()) return std::nullopt; - - if (accept.toBool(conditionResult.value())) { - auto result = accept(ast->iftrueExpression); - return result; - } - - auto result = accept(ast->iffalseExpression); - - return result; -} - -auto ASTInterpreter::ExpressionVisitor::operator()(YieldExpressionAST* ast) - -> ExpressionResult { - auto expressionResult = accept(ast->expression); - - return ExpressionResult{std::nullopt}; -} - -auto ASTInterpreter::ExpressionVisitor::operator()(ThrowExpressionAST* ast) - -> ExpressionResult { - auto expressionResult = accept(ast->expression); - - return ExpressionResult{std::nullopt}; -} - -auto ASTInterpreter::ExpressionVisitor::operator()(AssignmentExpressionAST* ast) - -> ExpressionResult { - auto leftExpressionResult = accept(ast->leftExpression); - auto rightExpressionResult = accept(ast->rightExpression); - - return ExpressionResult{std::nullopt}; -} - -auto ASTInterpreter::ExpressionVisitor::operator()( - CompoundAssignmentExpressionAST* ast) -> ExpressionResult { - auto leftExpressionResult = accept(ast->leftExpression); - auto rightExpressionResult = accept(ast->rightExpression); - - return ExpressionResult{std::nullopt}; -} - -auto ASTInterpreter::ExpressionVisitor::operator()( - PackExpansionExpressionAST* ast) -> ExpressionResult { - auto expressionResult = accept(ast->expression); - - return ExpressionResult{std::nullopt}; -} - -auto ASTInterpreter::ExpressionVisitor::operator()( - DesignatedInitializerClauseAST* ast) -> ExpressionResult { - auto initializerResult = accept(ast->initializer); - - return ExpressionResult{std::nullopt}; -} - -auto ASTInterpreter::ExpressionVisitor::operator()(TypeTraitExpressionAST* ast) - -> ExpressionResult { -#if false - for (auto node : ListView{ast->typeIdList}) { - auto value = accept(node); - } -#endif - - const Type* firstType = nullptr; - const Type* secondType = nullptr; - - if (ast->typeIdList && ast->typeIdList->value) { - firstType = ast->typeIdList->value->type; - - if (auto next = ast->typeIdList->next; next && next->value) { - secondType = next->value->type; - } - } - - if (firstType) { - switch (ast->typeTrait) { - case BuiltinTypeTraitKind::T___IS_VOID: - return control()->is_void(firstType); - - case BuiltinTypeTraitKind::T___IS_NULL_POINTER: - return control()->is_null_pointer(firstType); - - case BuiltinTypeTraitKind::T___IS_INTEGRAL: - return control()->is_integral(firstType); - - case BuiltinTypeTraitKind::T___IS_FLOATING_POINT: - return control()->is_floating_point(firstType); - - case BuiltinTypeTraitKind::T___IS_ARRAY: - return control()->is_array(firstType); - - case BuiltinTypeTraitKind::T___IS_ENUM: - return control()->is_enum(firstType); - - case BuiltinTypeTraitKind::T___IS_SCOPED_ENUM: - return control()->is_scoped_enum(firstType); - - case BuiltinTypeTraitKind::T___IS_UNION: - return control()->is_union(firstType); - - case BuiltinTypeTraitKind::T___IS_CLASS: - return control()->is_class(firstType); - - case BuiltinTypeTraitKind::T___IS_FUNCTION: - return control()->is_function(firstType); - - case BuiltinTypeTraitKind::T___IS_POINTER: - return control()->is_pointer(firstType); - - case BuiltinTypeTraitKind::T___IS_MEMBER_OBJECT_POINTER: - return control()->is_member_object_pointer(firstType); - - case BuiltinTypeTraitKind::T___IS_MEMBER_FUNCTION_POINTER: - return control()->is_member_function_pointer(firstType); - - case BuiltinTypeTraitKind::T___IS_LVALUE_REFERENCE: - return control()->is_lvalue_reference(firstType); - - case BuiltinTypeTraitKind::T___IS_RVALUE_REFERENCE: - return control()->is_rvalue_reference(firstType); - - case BuiltinTypeTraitKind::T___IS_FUNDAMENTAL: - return control()->is_fundamental(firstType); - - case BuiltinTypeTraitKind::T___IS_ARITHMETIC: - return control()->is_arithmetic(firstType); - - case BuiltinTypeTraitKind::T___IS_SCALAR: - return control()->is_scalar(firstType); - - case BuiltinTypeTraitKind::T___IS_OBJECT: - return control()->is_object(firstType); - - case BuiltinTypeTraitKind::T___IS_COMPOUND: - return control()->is_compound(firstType); - - case BuiltinTypeTraitKind::T___IS_REFERENCE: - return control()->is_reference(firstType); - - case BuiltinTypeTraitKind::T___IS_MEMBER_POINTER: - return control()->is_member_pointer(firstType); - - case BuiltinTypeTraitKind::T___IS_BOUNDED_ARRAY: - return control()->is_bounded_array(firstType); - - case BuiltinTypeTraitKind::T___IS_UNBOUNDED_ARRAY: - return control()->is_unbounded_array(firstType); - - case BuiltinTypeTraitKind::T___IS_CONST: - return control()->is_const(firstType); - - case BuiltinTypeTraitKind::T___IS_VOLATILE: - return control()->is_volatile(firstType); - - case BuiltinTypeTraitKind::T___IS_SIGNED: - return control()->is_signed(firstType); - - case BuiltinTypeTraitKind::T___IS_UNSIGNED: - return control()->is_unsigned(firstType); - - case BuiltinTypeTraitKind::T___IS_SAME: - case BuiltinTypeTraitKind::T___IS_SAME_AS: { - if (!secondType) break; - return control()->is_same(firstType, secondType); - } - - case BuiltinTypeTraitKind::T___IS_BASE_OF: { - if (!secondType) break; - return control()->is_base_of(firstType, secondType); - } - - case BuiltinTypeTraitKind::T___HAS_UNIQUE_OBJECT_REPRESENTATIONS: { - break; - } - - case BuiltinTypeTraitKind::T___HAS_VIRTUAL_DESTRUCTOR: { - break; - } - - case BuiltinTypeTraitKind::T___IS_ABSTRACT: { - break; - } - - case BuiltinTypeTraitKind::T___IS_AGGREGATE: { - break; - } - - case BuiltinTypeTraitKind::T___IS_ASSIGNABLE: { - break; - } - - case BuiltinTypeTraitKind::T___IS_EMPTY: { - break; - } - - case BuiltinTypeTraitKind::T___IS_FINAL: { - if (auto classType = - type_cast(control()->remove_cv(firstType))) { - return classType->symbol()->isFinal(); - } - break; - } - - case BuiltinTypeTraitKind::T___IS_LAYOUT_COMPATIBLE: { - break; - } - - case BuiltinTypeTraitKind::T___IS_LITERAL_TYPE: { - break; - } - - case BuiltinTypeTraitKind::T___IS_POD: { - break; - } - - case BuiltinTypeTraitKind::T___IS_POLYMORPHIC: { - break; - } - - case BuiltinTypeTraitKind::T___IS_STANDARD_LAYOUT: { - break; - } - - case BuiltinTypeTraitKind::T___IS_SWAPPABLE_WITH: { - break; - } - - case BuiltinTypeTraitKind::T___IS_TRIVIAL: { - break; - } - - case BuiltinTypeTraitKind::T___IS_TRIVIALLY_CONSTRUCTIBLE: { - break; - } - - case BuiltinTypeTraitKind::T___IS_TRIVIALLY_ASSIGNABLE: { - break; - } - - case BuiltinTypeTraitKind::T_NONE: { - // not a builtin - break; - } - - } // switch - } - - return std::nullopt; -} - -auto ASTInterpreter::ExpressionVisitor::operator()(ConditionExpressionAST* ast) - -> ExpressionResult { - for (auto node : ListView{ast->attributeList}) { - auto value = accept(node); - } - - for (auto node : ListView{ast->declSpecifierList}) { - auto value = accept(node); - } - - auto declaratorResult = accept(ast->declarator); - auto initializerResult = accept(ast->initializer); - - return ExpressionResult{std::nullopt}; -} - -auto ASTInterpreter::ExpressionVisitor::operator()(EqualInitializerAST* ast) - -> ExpressionResult { - auto expressionResult = accept(ast->expression); - - return expressionResult; -} - -auto ASTInterpreter::ExpressionVisitor::operator()(BracedInitListAST* ast) - -> ExpressionResult { - for (auto node : ListView{ast->expressionList}) { - auto value = accept(node); - } - - return ExpressionResult{std::nullopt}; -} - -auto ASTInterpreter::ExpressionVisitor::operator()(ParenInitializerAST* ast) - -> ExpressionResult { - for (auto node : ListView{ast->expressionList}) { - auto value = accept(node); - } - - return ExpressionResult{std::nullopt}; -} - -auto ASTInterpreter::TemplateParameterVisitor::operator()( - TemplateTypeParameterAST* ast) -> TemplateParameterResult { - for (auto node : ListView{ast->templateParameterList}) { - auto value = accept(node); - } - - auto requiresClauseResult = accept(ast->requiresClause); - auto idExpressionResult = accept(ast->idExpression); - - return {}; -} - -auto ASTInterpreter::TemplateParameterVisitor::operator()( - NonTypeTemplateParameterAST* ast) -> TemplateParameterResult { - auto declarationResult = accept(ast->declaration); - - return {}; -} - -auto ASTInterpreter::TemplateParameterVisitor::operator()( - TypenameTypeParameterAST* ast) -> TemplateParameterResult { - auto typeIdResult = accept(ast->typeId); - - return {}; -} - -auto ASTInterpreter::TemplateParameterVisitor::operator()( - ConstraintTypeParameterAST* ast) -> TemplateParameterResult { - auto typeConstraintResult = accept(ast->typeConstraint); - auto typeIdResult = accept(ast->typeId); - - return {}; -} - -auto ASTInterpreter::SpecifierVisitor::operator()(TypedefSpecifierAST* ast) - -> SpecifierResult { - return {}; -} - -auto ASTInterpreter::SpecifierVisitor::operator()(FriendSpecifierAST* ast) - -> SpecifierResult { - return {}; -} - -auto ASTInterpreter::SpecifierVisitor::operator()(ConstevalSpecifierAST* ast) - -> SpecifierResult { - return {}; -} - -auto ASTInterpreter::SpecifierVisitor::operator()(ConstinitSpecifierAST* ast) - -> SpecifierResult { - return {}; -} - -auto ASTInterpreter::SpecifierVisitor::operator()(ConstexprSpecifierAST* ast) - -> SpecifierResult { - return {}; -} - -auto ASTInterpreter::SpecifierVisitor::operator()(InlineSpecifierAST* ast) - -> SpecifierResult { - return {}; -} - -auto ASTInterpreter::SpecifierVisitor::operator()(NoreturnSpecifierAST* ast) - -> SpecifierResult { - return {}; -} - -auto ASTInterpreter::SpecifierVisitor::operator()(StaticSpecifierAST* ast) - -> SpecifierResult { - return {}; -} - -auto ASTInterpreter::SpecifierVisitor::operator()(ExternSpecifierAST* ast) - -> SpecifierResult { - return {}; -} - -auto ASTInterpreter::SpecifierVisitor::operator()(RegisterSpecifierAST* ast) - -> SpecifierResult { - return {}; -} - -auto ASTInterpreter::SpecifierVisitor::operator()(ThreadLocalSpecifierAST* ast) - -> SpecifierResult { - return {}; -} - -auto ASTInterpreter::SpecifierVisitor::operator()(ThreadSpecifierAST* ast) - -> SpecifierResult { - return {}; -} - -auto ASTInterpreter::SpecifierVisitor::operator()(MutableSpecifierAST* ast) - -> SpecifierResult { - return {}; -} - -auto ASTInterpreter::SpecifierVisitor::operator()(VirtualSpecifierAST* ast) - -> SpecifierResult { - return {}; -} - -auto ASTInterpreter::SpecifierVisitor::operator()(ExplicitSpecifierAST* ast) - -> SpecifierResult { - auto expressionResult = accept(ast->expression); - - return {}; -} - -auto ASTInterpreter::SpecifierVisitor::operator()(AutoTypeSpecifierAST* ast) - -> SpecifierResult { - return {}; -} - -auto ASTInterpreter::SpecifierVisitor::operator()(VoidTypeSpecifierAST* ast) - -> SpecifierResult { - return {}; -} - -auto ASTInterpreter::SpecifierVisitor::operator()(SizeTypeSpecifierAST* ast) - -> SpecifierResult { - return {}; -} - -auto ASTInterpreter::SpecifierVisitor::operator()(SignTypeSpecifierAST* ast) - -> SpecifierResult { - return {}; -} - -auto ASTInterpreter::SpecifierVisitor::operator()(BuiltinTypeSpecifierAST* ast) - -> SpecifierResult { - return {}; -} - -auto ASTInterpreter::SpecifierVisitor::operator()( - UnaryBuiltinTypeSpecifierAST* ast) -> SpecifierResult { - return {}; -} - -auto ASTInterpreter::SpecifierVisitor::operator()( - BinaryBuiltinTypeSpecifierAST* ast) -> SpecifierResult { - return {}; -} - -auto ASTInterpreter::SpecifierVisitor::operator()(IntegralTypeSpecifierAST* ast) - -> SpecifierResult { - return {}; -} - -auto ASTInterpreter::SpecifierVisitor::operator()( - FloatingPointTypeSpecifierAST* ast) -> SpecifierResult { - return {}; -} - -auto ASTInterpreter::SpecifierVisitor::operator()(ComplexTypeSpecifierAST* ast) - -> SpecifierResult { - return {}; -} - -auto ASTInterpreter::SpecifierVisitor::operator()(NamedTypeSpecifierAST* ast) - -> SpecifierResult { - auto nestedNameSpecifierResult = accept(ast->nestedNameSpecifier); - auto unqualifiedIdResult = accept(ast->unqualifiedId); - - return {}; -} - -auto ASTInterpreter::SpecifierVisitor::operator()(AtomicTypeSpecifierAST* ast) - -> SpecifierResult { - auto typeIdResult = accept(ast->typeId); - - return {}; -} - -auto ASTInterpreter::SpecifierVisitor::operator()( - UnderlyingTypeSpecifierAST* ast) -> SpecifierResult { - auto typeIdResult = accept(ast->typeId); - - return {}; -} - -auto ASTInterpreter::SpecifierVisitor::operator()( - ElaboratedTypeSpecifierAST* ast) -> SpecifierResult { - for (auto node : ListView{ast->attributeList}) { - auto value = accept(node); - } - - auto nestedNameSpecifierResult = accept(ast->nestedNameSpecifier); - auto unqualifiedIdResult = accept(ast->unqualifiedId); - - return {}; -} - -auto ASTInterpreter::SpecifierVisitor::operator()(DecltypeAutoSpecifierAST* ast) - -> SpecifierResult { - return {}; -} - -auto ASTInterpreter::SpecifierVisitor::operator()(DecltypeSpecifierAST* ast) - -> SpecifierResult { - auto expressionResult = accept(ast->expression); - - return {}; -} - -auto ASTInterpreter::SpecifierVisitor::operator()( - PlaceholderTypeSpecifierAST* ast) -> SpecifierResult { - auto typeConstraintResult = accept(ast->typeConstraint); - auto specifierResult = accept(ast->specifier); - - return {}; -} - -auto ASTInterpreter::SpecifierVisitor::operator()(ConstQualifierAST* ast) - -> SpecifierResult { - return {}; -} - -auto ASTInterpreter::SpecifierVisitor::operator()(VolatileQualifierAST* ast) - -> SpecifierResult { - return {}; -} - -auto ASTInterpreter::SpecifierVisitor::operator()(RestrictQualifierAST* ast) - -> SpecifierResult { - return {}; -} - -auto ASTInterpreter::SpecifierVisitor::operator()(AtomicQualifierAST* ast) - -> SpecifierResult { - return {}; -} - -auto ASTInterpreter::SpecifierVisitor::operator()(EnumSpecifierAST* ast) - -> SpecifierResult { - for (auto node : ListView{ast->attributeList}) { - auto value = accept(node); - } - - auto nestedNameSpecifierResult = accept(ast->nestedNameSpecifier); - auto unqualifiedIdResult = accept(ast->unqualifiedId); - - for (auto node : ListView{ast->typeSpecifierList}) { - auto value = accept(node); - } - - for (auto node : ListView{ast->enumeratorList}) { - auto value = accept(node); - } - - return {}; -} - -auto ASTInterpreter::SpecifierVisitor::operator()(ClassSpecifierAST* ast) - -> SpecifierResult { - for (auto node : ListView{ast->attributeList}) { - auto value = accept(node); - } - - auto nestedNameSpecifierResult = accept(ast->nestedNameSpecifier); - auto unqualifiedIdResult = accept(ast->unqualifiedId); - - for (auto node : ListView{ast->baseSpecifierList}) { - auto value = accept(node); - } - - for (auto node : ListView{ast->declarationList}) { - auto value = accept(node); - } - - return {}; -} - -auto ASTInterpreter::SpecifierVisitor::operator()(TypenameSpecifierAST* ast) - -> SpecifierResult { - auto nestedNameSpecifierResult = accept(ast->nestedNameSpecifier); - auto unqualifiedIdResult = accept(ast->unqualifiedId); - - return {}; -} - -auto ASTInterpreter::SpecifierVisitor::operator()(SplicerTypeSpecifierAST* ast) - -> SpecifierResult { - auto splicerResult = accept(ast->splicer); - - return {}; -} - -auto ASTInterpreter::PtrOperatorVisitor::operator()(PointerOperatorAST* ast) - -> PtrOperatorResult { - for (auto node : ListView{ast->attributeList}) { - auto value = accept(node); - } - - for (auto node : ListView{ast->cvQualifierList}) { - auto value = accept(node); - } - - return {}; -} - -auto ASTInterpreter::PtrOperatorVisitor::operator()(ReferenceOperatorAST* ast) - -> PtrOperatorResult { - for (auto node : ListView{ast->attributeList}) { - auto value = accept(node); - } - - return {}; -} - -auto ASTInterpreter::PtrOperatorVisitor::operator()(PtrToMemberOperatorAST* ast) - -> PtrOperatorResult { - auto nestedNameSpecifierResult = accept(ast->nestedNameSpecifier); - - for (auto node : ListView{ast->attributeList}) { - auto value = accept(node); - } - - for (auto node : ListView{ast->cvQualifierList}) { - auto value = accept(node); - } - - return {}; -} - -auto ASTInterpreter::CoreDeclaratorVisitor::operator()( - BitfieldDeclaratorAST* ast) -> CoreDeclaratorResult { - auto unqualifiedIdResult = accept(ast->unqualifiedId); - auto sizeExpressionResult = accept(ast->sizeExpression); - - return {}; -} - -auto ASTInterpreter::CoreDeclaratorVisitor::operator()(ParameterPackAST* ast) - -> CoreDeclaratorResult { - auto coreDeclaratorResult = accept(ast->coreDeclarator); - - return {}; -} - -auto ASTInterpreter::CoreDeclaratorVisitor::operator()(IdDeclaratorAST* ast) - -> CoreDeclaratorResult { - auto nestedNameSpecifierResult = accept(ast->nestedNameSpecifier); - auto unqualifiedIdResult = accept(ast->unqualifiedId); - - for (auto node : ListView{ast->attributeList}) { - auto value = accept(node); - } - - return {}; -} - -auto ASTInterpreter::CoreDeclaratorVisitor::operator()(NestedDeclaratorAST* ast) - -> CoreDeclaratorResult { - auto declaratorResult = accept(ast->declarator); - - return {}; -} - -auto ASTInterpreter::DeclaratorChunkVisitor::operator()( - FunctionDeclaratorChunkAST* ast) -> DeclaratorChunkResult { - auto parameterDeclarationClauseResult = - accept(ast->parameterDeclarationClause); - - for (auto node : ListView{ast->cvQualifierList}) { - auto value = accept(node); - } - - auto exceptionSpecifierResult = accept(ast->exceptionSpecifier); - - for (auto node : ListView{ast->attributeList}) { - auto value = accept(node); - } - - auto trailingReturnTypeResult = accept(ast->trailingReturnType); - - return {}; -} - -auto ASTInterpreter::DeclaratorChunkVisitor::operator()( - ArrayDeclaratorChunkAST* ast) -> DeclaratorChunkResult { - auto expressionResult = accept(ast->expression); - - for (auto node : ListView{ast->attributeList}) { - auto value = accept(node); - } - - return {}; -} - -auto ASTInterpreter::UnqualifiedIdVisitor::operator()(NameIdAST* ast) - -> UnqualifiedIdResult { - return {}; -} - -auto ASTInterpreter::UnqualifiedIdVisitor::operator()(DestructorIdAST* ast) - -> UnqualifiedIdResult { - auto idResult = accept(ast->id); - - return {}; -} - -auto ASTInterpreter::UnqualifiedIdVisitor::operator()(DecltypeIdAST* ast) - -> UnqualifiedIdResult { - auto decltypeSpecifierResult = accept(ast->decltypeSpecifier); - - return {}; -} - -auto ASTInterpreter::UnqualifiedIdVisitor::operator()( - OperatorFunctionIdAST* ast) -> UnqualifiedIdResult { - return {}; -} - -auto ASTInterpreter::UnqualifiedIdVisitor::operator()(LiteralOperatorIdAST* ast) - -> UnqualifiedIdResult { - return {}; -} - -auto ASTInterpreter::UnqualifiedIdVisitor::operator()( - ConversionFunctionIdAST* ast) -> UnqualifiedIdResult { - auto typeIdResult = accept(ast->typeId); - - return {}; -} - -auto ASTInterpreter::UnqualifiedIdVisitor::operator()(SimpleTemplateIdAST* ast) - -> UnqualifiedIdResult { - for (auto node : ListView{ast->templateArgumentList}) { - auto value = accept(node); - } - - return {}; -} - -auto ASTInterpreter::UnqualifiedIdVisitor::operator()( - LiteralOperatorTemplateIdAST* ast) -> UnqualifiedIdResult { - auto literalOperatorIdResult = accept(ast->literalOperatorId); - - for (auto node : ListView{ast->templateArgumentList}) { - auto value = accept(node); - } - - return {}; -} - -auto ASTInterpreter::UnqualifiedIdVisitor::operator()( - OperatorFunctionTemplateIdAST* ast) -> UnqualifiedIdResult { - auto operatorFunctionIdResult = accept(ast->operatorFunctionId); - - for (auto node : ListView{ast->templateArgumentList}) { - auto value = accept(node); - } - - return {}; -} - -auto ASTInterpreter::NestedNameSpecifierVisitor::operator()( - GlobalNestedNameSpecifierAST* ast) -> NestedNameSpecifierResult { - return {}; -} - -auto ASTInterpreter::NestedNameSpecifierVisitor::operator()( - SimpleNestedNameSpecifierAST* ast) -> NestedNameSpecifierResult { - auto nestedNameSpecifierResult = accept(ast->nestedNameSpecifier); - - return {}; -} - -auto ASTInterpreter::NestedNameSpecifierVisitor::operator()( - DecltypeNestedNameSpecifierAST* ast) -> NestedNameSpecifierResult { - auto decltypeSpecifierResult = accept(ast->decltypeSpecifier); - - return {}; -} - -auto ASTInterpreter::NestedNameSpecifierVisitor::operator()( - TemplateNestedNameSpecifierAST* ast) -> NestedNameSpecifierResult { - auto nestedNameSpecifierResult = accept(ast->nestedNameSpecifier); - auto templateIdResult = accept(ast->templateId); - - return {}; -} - -auto ASTInterpreter::FunctionBodyVisitor::operator()( - DefaultFunctionBodyAST* ast) -> FunctionBodyResult { - return {}; -} - -auto ASTInterpreter::FunctionBodyVisitor::operator()( - CompoundStatementFunctionBodyAST* ast) -> FunctionBodyResult { - for (auto node : ListView{ast->memInitializerList}) { - auto value = accept(node); - } - - auto statementResult = accept(ast->statement); - - return {}; -} - -auto ASTInterpreter::FunctionBodyVisitor::operator()( - TryStatementFunctionBodyAST* ast) -> FunctionBodyResult { - for (auto node : ListView{ast->memInitializerList}) { - auto value = accept(node); - } - - auto statementResult = accept(ast->statement); - - for (auto node : ListView{ast->handlerList}) { - auto value = accept(node); - } - - return {}; -} - -auto ASTInterpreter::FunctionBodyVisitor::operator()(DeleteFunctionBodyAST* ast) - -> FunctionBodyResult { - return {}; -} - -auto ASTInterpreter::TemplateArgumentVisitor::operator()( - TypeTemplateArgumentAST* ast) -> TemplateArgumentResult { - auto typeIdResult = accept(ast->typeId); - - return {}; -} - -auto ASTInterpreter::TemplateArgumentVisitor::operator()( - ExpressionTemplateArgumentAST* ast) -> TemplateArgumentResult { - auto expressionResult = accept(ast->expression); - - return {}; -} - -auto ASTInterpreter::ExceptionSpecifierVisitor::operator()( - ThrowExceptionSpecifierAST* ast) -> ExceptionSpecifierResult { - return {}; -} - -auto ASTInterpreter::ExceptionSpecifierVisitor::operator()( - NoexceptSpecifierAST* ast) -> ExceptionSpecifierResult { - auto expressionResult = accept(ast->expression); - - return {}; -} - -auto ASTInterpreter::RequirementVisitor::operator()(SimpleRequirementAST* ast) - -> RequirementResult { - auto expressionResult = accept(ast->expression); - - return {}; -} - -auto ASTInterpreter::RequirementVisitor::operator()(CompoundRequirementAST* ast) - -> RequirementResult { - auto expressionResult = accept(ast->expression); - auto typeConstraintResult = accept(ast->typeConstraint); - - return {}; -} - -auto ASTInterpreter::RequirementVisitor::operator()(TypeRequirementAST* ast) - -> RequirementResult { - auto nestedNameSpecifierResult = accept(ast->nestedNameSpecifier); - auto unqualifiedIdResult = accept(ast->unqualifiedId); - - return {}; -} - -auto ASTInterpreter::RequirementVisitor::operator()(NestedRequirementAST* ast) - -> RequirementResult { - auto expressionResult = accept(ast->expression); - - return {}; -} - -auto ASTInterpreter::NewInitializerVisitor::operator()( - NewParenInitializerAST* ast) -> NewInitializerResult { - for (auto node : ListView{ast->expressionList}) { - auto value = accept(node); - } - - return {}; -} - -auto ASTInterpreter::NewInitializerVisitor::operator()( - NewBracedInitializerAST* ast) -> NewInitializerResult { - auto bracedInitListResult = accept(ast->bracedInitList); - - return {}; -} - -auto ASTInterpreter::MemInitializerVisitor::operator()( - ParenMemInitializerAST* ast) -> MemInitializerResult { - auto nestedNameSpecifierResult = accept(ast->nestedNameSpecifier); - auto unqualifiedIdResult = accept(ast->unqualifiedId); - - for (auto node : ListView{ast->expressionList}) { - auto value = accept(node); - } - - return {}; -} - -auto ASTInterpreter::MemInitializerVisitor::operator()( - BracedMemInitializerAST* ast) -> MemInitializerResult { - auto nestedNameSpecifierResult = accept(ast->nestedNameSpecifier); - auto unqualifiedIdResult = accept(ast->unqualifiedId); - auto bracedInitListResult = accept(ast->bracedInitList); - - return {}; -} - -auto ASTInterpreter::LambdaCaptureVisitor::operator()(ThisLambdaCaptureAST* ast) - -> LambdaCaptureResult { - return {}; -} - -auto ASTInterpreter::LambdaCaptureVisitor::operator()( - DerefThisLambdaCaptureAST* ast) -> LambdaCaptureResult { - return {}; -} - -auto ASTInterpreter::LambdaCaptureVisitor::operator()( - SimpleLambdaCaptureAST* ast) -> LambdaCaptureResult { - return {}; -} - -auto ASTInterpreter::LambdaCaptureVisitor::operator()(RefLambdaCaptureAST* ast) - -> LambdaCaptureResult { - return {}; -} - -auto ASTInterpreter::LambdaCaptureVisitor::operator()( - RefInitLambdaCaptureAST* ast) -> LambdaCaptureResult { - auto initializerResult = accept(ast->initializer); - - return {}; -} - -auto ASTInterpreter::LambdaCaptureVisitor::operator()(InitLambdaCaptureAST* ast) - -> LambdaCaptureResult { - auto initializerResult = accept(ast->initializer); - - return {}; -} - -auto ASTInterpreter::ExceptionDeclarationVisitor::operator()( - EllipsisExceptionDeclarationAST* ast) -> ExceptionDeclarationResult { - return {}; -} - -auto ASTInterpreter::ExceptionDeclarationVisitor::operator()( - TypeExceptionDeclarationAST* ast) -> ExceptionDeclarationResult { - for (auto node : ListView{ast->attributeList}) { - auto value = accept(node); - } - - for (auto node : ListView{ast->typeSpecifierList}) { - auto value = accept(node); - } - - auto declaratorResult = accept(ast->declarator); - - return {}; -} - -auto ASTInterpreter::AttributeSpecifierVisitor::operator()(CxxAttributeAST* ast) - -> AttributeSpecifierResult { - auto attributeUsingPrefixResult = accept(ast->attributeUsingPrefix); - - for (auto node : ListView{ast->attributeList}) { - auto value = accept(node); - } - - return {}; -} - -auto ASTInterpreter::AttributeSpecifierVisitor::operator()(GccAttributeAST* ast) - -> AttributeSpecifierResult { - return {}; -} - -auto ASTInterpreter::AttributeSpecifierVisitor::operator()( - AlignasAttributeAST* ast) -> AttributeSpecifierResult { - auto expressionResult = accept(ast->expression); - - return {}; -} - -auto ASTInterpreter::AttributeSpecifierVisitor::operator()( - AlignasTypeAttributeAST* ast) -> AttributeSpecifierResult { - auto typeIdResult = accept(ast->typeId); - - return {}; -} - -auto ASTInterpreter::AttributeSpecifierVisitor::operator()(AsmAttributeAST* ast) - -> AttributeSpecifierResult { - return {}; -} - -auto ASTInterpreter::AttributeTokenVisitor::operator()( - ScopedAttributeTokenAST* ast) -> AttributeTokenResult { - return {}; -} - -auto ASTInterpreter::AttributeTokenVisitor::operator()( - SimpleAttributeTokenAST* ast) -> AttributeTokenResult { - return {}; -} - ASTInterpreter::ASTInterpreter(TranslationUnit* unit) : unit_(unit) {} ASTInterpreter::~ASTInterpreter() {} @@ -3571,7 +104,7 @@ ASTInterpreter::~ASTInterpreter() {} auto ASTInterpreter::control() const -> Control* { return unit_->control(); } auto ASTInterpreter::evaluate(ExpressionAST* ast) -> std::optional { - auto result = operator()(ast); + auto result = expression(ast); return result; } diff --git a/src/parser/cxx/ast_interpreter.h b/src/parser/cxx/ast_interpreter.h index c3419ae6..c4e0c483 100644 --- a/src/parser/cxx/ast_interpreter.h +++ b/src/parser/cxx/ast_interpreter.h @@ -62,51 +62,51 @@ class ASTInterpreter { using ExpressionResult = std::optional; // base nodes - struct UnitResult; - struct DeclarationResult; - struct StatementResult; - struct TemplateParameterResult; - struct SpecifierResult; - struct PtrOperatorResult; - struct CoreDeclaratorResult; - struct DeclaratorChunkResult; - struct UnqualifiedIdResult; - struct NestedNameSpecifierResult; - struct FunctionBodyResult; - struct TemplateArgumentResult; - struct ExceptionSpecifierResult; - struct RequirementResult; - struct NewInitializerResult; - struct MemInitializerResult; - struct LambdaCaptureResult; - struct ExceptionDeclarationResult; - struct AttributeSpecifierResult; - struct AttributeTokenResult; + struct UnitResult {}; + struct DeclarationResult {}; + struct StatementResult {}; + struct TemplateParameterResult {}; + struct SpecifierResult {}; + struct PtrOperatorResult {}; + struct CoreDeclaratorResult {}; + struct DeclaratorChunkResult {}; + struct UnqualifiedIdResult {}; + struct NestedNameSpecifierResult {}; + struct FunctionBodyResult {}; + struct TemplateArgumentResult {}; + struct ExceptionSpecifierResult {}; + struct RequirementResult {}; + struct NewInitializerResult {}; + struct MemInitializerResult {}; + struct LambdaCaptureResult {}; + struct ExceptionDeclarationResult {}; + struct AttributeSpecifierResult {}; + struct AttributeTokenResult {}; // misc nodes - struct GlobalModuleFragmentResult; - struct PrivateModuleFragmentResult; - struct ModuleDeclarationResult; - struct ModuleNameResult; - struct ModuleQualifierResult; - struct ModulePartitionResult; - struct ImportNameResult; - struct InitDeclaratorResult; - struct DeclaratorResult; - struct UsingDeclaratorResult; - struct EnumeratorResult; - struct TypeIdResult; - struct HandlerResult; - struct BaseSpecifierResult; - struct RequiresClauseResult; - struct ParameterDeclarationClauseResult; - struct TrailingReturnTypeResult; - struct LambdaSpecifierResult; - struct TypeConstraintResult; - struct AttributeArgumentClauseResult; - struct AttributeResult; - struct AttributeUsingPrefixResult; - struct NewPlacementResult; - struct NestedNamespaceSpecifierResult; + struct GlobalModuleFragmentResult {}; + struct PrivateModuleFragmentResult {}; + struct ModuleDeclarationResult {}; + struct ModuleNameResult {}; + struct ModuleQualifierResult {}; + struct ModulePartitionResult {}; + struct ImportNameResult {}; + struct InitDeclaratorResult {}; + struct DeclaratorResult {}; + struct UsingDeclaratorResult {}; + struct EnumeratorResult {}; + struct TypeIdResult {}; + struct HandlerResult {}; + struct BaseSpecifierResult {}; + struct RequiresClauseResult {}; + struct ParameterDeclarationClauseResult {}; + struct TrailingReturnTypeResult {}; + struct LambdaSpecifierResult {}; + struct TypeConstraintResult {}; + struct AttributeArgumentClauseResult {}; + struct AttributeResult {}; + struct AttributeUsingPrefixResult {}; + struct NewPlacementResult {}; + struct NestedNamespaceSpecifierResult {}; // visitors struct UnitVisitor; struct DeclarationVisitor; @@ -134,77 +134,87 @@ class ASTInterpreter { struct ToBool; // run on the base nodes - [[nodiscard]] auto operator()(UnitAST* ast) -> UnitResult; - [[nodiscard]] auto operator()(DeclarationAST* ast) -> DeclarationResult; - [[nodiscard]] auto operator()(StatementAST* ast) -> StatementResult; - [[nodiscard]] auto operator()(ExpressionAST* ast) -> ExpressionResult; - [[nodiscard]] auto operator()(TemplateParameterAST* ast) + [[nodiscard]] auto unit(UnitAST* ast) -> UnitResult; + [[nodiscard]] auto declaration(DeclarationAST* ast) -> DeclarationResult; + [[nodiscard]] auto statement(StatementAST* ast) -> StatementResult; + [[nodiscard]] auto expression(ExpressionAST* ast) -> ExpressionResult; + [[nodiscard]] auto templateParameter(TemplateParameterAST* ast) -> TemplateParameterResult; - [[nodiscard]] auto operator()(SpecifierAST* ast) -> SpecifierResult; - [[nodiscard]] auto operator()(PtrOperatorAST* ast) -> PtrOperatorResult; - [[nodiscard]] auto operator()(CoreDeclaratorAST* ast) -> CoreDeclaratorResult; - [[nodiscard]] auto operator()(DeclaratorChunkAST* ast) + [[nodiscard]] auto specifier(SpecifierAST* ast) -> SpecifierResult; + [[nodiscard]] auto ptrOperator(PtrOperatorAST* ast) -> PtrOperatorResult; + [[nodiscard]] auto coreDeclarator(CoreDeclaratorAST* ast) + -> CoreDeclaratorResult; + [[nodiscard]] auto declaratorChunk(DeclaratorChunkAST* ast) -> DeclaratorChunkResult; - [[nodiscard]] auto operator()(UnqualifiedIdAST* ast) -> UnqualifiedIdResult; - [[nodiscard]] auto operator()(NestedNameSpecifierAST* ast) + [[nodiscard]] auto unqualifiedId(UnqualifiedIdAST* ast) + -> UnqualifiedIdResult; + [[nodiscard]] auto nestedNameSpecifier(NestedNameSpecifierAST* ast) -> NestedNameSpecifierResult; - [[nodiscard]] auto operator()(FunctionBodyAST* ast) -> FunctionBodyResult; - [[nodiscard]] auto operator()(TemplateArgumentAST* ast) + [[nodiscard]] auto functionBody(FunctionBodyAST* ast) -> FunctionBodyResult; + [[nodiscard]] auto templateArgument(TemplateArgumentAST* ast) -> TemplateArgumentResult; - [[nodiscard]] auto operator()(ExceptionSpecifierAST* ast) + [[nodiscard]] auto exceptionSpecifier(ExceptionSpecifierAST* ast) -> ExceptionSpecifierResult; - [[nodiscard]] auto operator()(RequirementAST* ast) -> RequirementResult; - [[nodiscard]] auto operator()(NewInitializerAST* ast) -> NewInitializerResult; - [[nodiscard]] auto operator()(MemInitializerAST* ast) -> MemInitializerResult; - [[nodiscard]] auto operator()(LambdaCaptureAST* ast) -> LambdaCaptureResult; - [[nodiscard]] auto operator()(ExceptionDeclarationAST* ast) + [[nodiscard]] auto requirement(RequirementAST* ast) -> RequirementResult; + [[nodiscard]] auto newInitializer(NewInitializerAST* ast) + -> NewInitializerResult; + [[nodiscard]] auto memInitializer(MemInitializerAST* ast) + -> MemInitializerResult; + [[nodiscard]] auto lambdaCapture(LambdaCaptureAST* ast) + -> LambdaCaptureResult; + [[nodiscard]] auto exceptionDeclaration(ExceptionDeclarationAST* ast) -> ExceptionDeclarationResult; - [[nodiscard]] auto operator()(AttributeSpecifierAST* ast) + [[nodiscard]] auto attributeSpecifier(AttributeSpecifierAST* ast) -> AttributeSpecifierResult; - [[nodiscard]] auto operator()(AttributeTokenAST* ast) -> AttributeTokenResult; + [[nodiscard]] auto attributeToken(AttributeTokenAST* ast) + -> AttributeTokenResult; // run on the misc nodes - [[nodiscard]] auto operator()(SplicerAST* ast) -> ExpressionResult; - [[nodiscard]] auto operator()(GlobalModuleFragmentAST* ast) + [[nodiscard]] auto splicer(SplicerAST* ast) -> ExpressionResult; + [[nodiscard]] auto globalModuleFragment(GlobalModuleFragmentAST* ast) -> GlobalModuleFragmentResult; - [[nodiscard]] auto operator()(PrivateModuleFragmentAST* ast) + [[nodiscard]] auto privateModuleFragment(PrivateModuleFragmentAST* ast) -> PrivateModuleFragmentResult; - [[nodiscard]] auto operator()(ModuleDeclarationAST* ast) + [[nodiscard]] auto moduleDeclaration(ModuleDeclarationAST* ast) -> ModuleDeclarationResult; - [[nodiscard]] auto operator()(ModuleNameAST* ast) -> ModuleNameResult; - [[nodiscard]] auto operator()(ModuleQualifierAST* ast) + [[nodiscard]] auto moduleName(ModuleNameAST* ast) -> ModuleNameResult; + [[nodiscard]] auto moduleQualifier(ModuleQualifierAST* ast) -> ModuleQualifierResult; - [[nodiscard]] auto operator()(ModulePartitionAST* ast) + [[nodiscard]] auto modulePartition(ModulePartitionAST* ast) -> ModulePartitionResult; - [[nodiscard]] auto operator()(ImportNameAST* ast) -> ImportNameResult; - [[nodiscard]] auto operator()(InitDeclaratorAST* ast) -> InitDeclaratorResult; - [[nodiscard]] auto operator()(DeclaratorAST* ast) -> DeclaratorResult; - [[nodiscard]] auto operator()(UsingDeclaratorAST* ast) + [[nodiscard]] auto importName(ImportNameAST* ast) -> ImportNameResult; + [[nodiscard]] auto initDeclarator(InitDeclaratorAST* ast) + -> InitDeclaratorResult; + [[nodiscard]] auto declarator(DeclaratorAST* ast) -> DeclaratorResult; + [[nodiscard]] auto usingDeclarator(UsingDeclaratorAST* ast) -> UsingDeclaratorResult; - [[nodiscard]] auto operator()(EnumeratorAST* ast) -> EnumeratorResult; - [[nodiscard]] auto operator()(TypeIdAST* ast) -> TypeIdResult; - [[nodiscard]] auto operator()(HandlerAST* ast) -> HandlerResult; - [[nodiscard]] auto operator()(BaseSpecifierAST* ast) -> BaseSpecifierResult; - [[nodiscard]] auto operator()(RequiresClauseAST* ast) -> RequiresClauseResult; - [[nodiscard]] auto operator()(ParameterDeclarationClauseAST* ast) - -> ParameterDeclarationClauseResult; - [[nodiscard]] auto operator()(TrailingReturnTypeAST* ast) + [[nodiscard]] auto enumerator(EnumeratorAST* ast) -> EnumeratorResult; + [[nodiscard]] auto typeId(TypeIdAST* ast) -> TypeIdResult; + [[nodiscard]] auto handler(HandlerAST* ast) -> HandlerResult; + [[nodiscard]] auto baseSpecifier(BaseSpecifierAST* ast) + -> BaseSpecifierResult; + [[nodiscard]] auto requiresClause(RequiresClauseAST* ast) + -> RequiresClauseResult; + [[nodiscard]] auto parameterDeclarationClause( + ParameterDeclarationClauseAST* ast) -> ParameterDeclarationClauseResult; + [[nodiscard]] auto trailingReturnType(TrailingReturnTypeAST* ast) -> TrailingReturnTypeResult; - [[nodiscard]] auto operator()(LambdaSpecifierAST* ast) + [[nodiscard]] auto lambdaSpecifier(LambdaSpecifierAST* ast) -> LambdaSpecifierResult; - [[nodiscard]] auto operator()(TypeConstraintAST* ast) -> TypeConstraintResult; - [[nodiscard]] auto operator()(AttributeArgumentClauseAST* ast) + [[nodiscard]] auto typeConstraint(TypeConstraintAST* ast) + -> TypeConstraintResult; + [[nodiscard]] auto attributeArgumentClause(AttributeArgumentClauseAST* ast) -> AttributeArgumentClauseResult; - [[nodiscard]] auto operator()(AttributeAST* ast) -> AttributeResult; - [[nodiscard]] auto operator()(AttributeUsingPrefixAST* ast) + [[nodiscard]] auto attribute(AttributeAST* ast) -> AttributeResult; + [[nodiscard]] auto attributeUsingPrefix(AttributeUsingPrefixAST* ast) -> AttributeUsingPrefixResult; - [[nodiscard]] auto operator()(NewPlacementAST* ast) -> NewPlacementResult; - [[nodiscard]] auto operator()(NestedNamespaceSpecifierAST* ast) + [[nodiscard]] auto newPlacement(NewPlacementAST* ast) -> NewPlacementResult; + [[nodiscard]] auto nestedNamespaceSpecifier(NestedNamespaceSpecifierAST* ast) -> NestedNamespaceSpecifierResult; - [[nodiscard]] auto operator()(AsmOperandAST* ast) -> DeclarationResult; - [[nodiscard]] auto operator()(AsmQualifierAST* ast) -> DeclarationResult; - [[nodiscard]] auto operator()(AsmClobberAST* ast) -> DeclarationResult; - [[nodiscard]] auto operator()(AsmGotoLabelAST* ast) -> DeclarationResult; + [[nodiscard]] auto asmOperand(AsmOperandAST* ast) -> DeclarationResult; + [[nodiscard]] auto asmQualifier(AsmQualifierAST* ast) -> DeclarationResult; + [[nodiscard]] auto asmClobber(AsmClobberAST* ast) -> DeclarationResult; + [[nodiscard]] auto asmGotoLabel(AsmGotoLabelAST* ast) -> DeclarationResult; private: TranslationUnit* unit_ = nullptr; diff --git a/src/parser/cxx/ast_interpreter_declarations.cc b/src/parser/cxx/ast_interpreter_declarations.cc new file mode 100644 index 00000000..72587de5 --- /dev/null +++ b/src/parser/cxx/ast_interpreter_declarations.cc @@ -0,0 +1,575 @@ +// Copyright (c) 2025 Roberto Raggi +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. + +#include + +// cxx +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +namespace cxx { + +struct ASTInterpreter::DeclarationVisitor { + ASTInterpreter& interp; + + [[nodiscard]] auto operator()(SimpleDeclarationAST* ast) -> DeclarationResult; + + [[nodiscard]] auto operator()(AsmDeclarationAST* ast) -> DeclarationResult; + + [[nodiscard]] auto operator()(NamespaceAliasDefinitionAST* ast) + -> DeclarationResult; + + [[nodiscard]] auto operator()(UsingDeclarationAST* ast) -> DeclarationResult; + + [[nodiscard]] auto operator()(UsingEnumDeclarationAST* ast) + -> DeclarationResult; + + [[nodiscard]] auto operator()(UsingDirectiveAST* ast) -> DeclarationResult; + + [[nodiscard]] auto operator()(StaticAssertDeclarationAST* ast) + -> DeclarationResult; + + [[nodiscard]] auto operator()(AliasDeclarationAST* ast) -> DeclarationResult; + + [[nodiscard]] auto operator()(OpaqueEnumDeclarationAST* ast) + -> DeclarationResult; + + [[nodiscard]] auto operator()(FunctionDefinitionAST* ast) + -> DeclarationResult; + + [[nodiscard]] auto operator()(TemplateDeclarationAST* ast) + -> DeclarationResult; + + [[nodiscard]] auto operator()(ConceptDefinitionAST* ast) -> DeclarationResult; + + [[nodiscard]] auto operator()(DeductionGuideAST* ast) -> DeclarationResult; + + [[nodiscard]] auto operator()(ExplicitInstantiationAST* ast) + -> DeclarationResult; + + [[nodiscard]] auto operator()(ExportDeclarationAST* ast) -> DeclarationResult; + + [[nodiscard]] auto operator()(ExportCompoundDeclarationAST* ast) + -> DeclarationResult; + + [[nodiscard]] auto operator()(LinkageSpecificationAST* ast) + -> DeclarationResult; + + [[nodiscard]] auto operator()(NamespaceDefinitionAST* ast) + -> DeclarationResult; + + [[nodiscard]] auto operator()(EmptyDeclarationAST* ast) -> DeclarationResult; + + [[nodiscard]] auto operator()(AttributeDeclarationAST* ast) + -> DeclarationResult; + + [[nodiscard]] auto operator()(ModuleImportDeclarationAST* ast) + -> DeclarationResult; + + [[nodiscard]] auto operator()(ParameterDeclarationAST* ast) + -> DeclarationResult; + + [[nodiscard]] auto operator()(AccessDeclarationAST* ast) -> DeclarationResult; + + [[nodiscard]] auto operator()(ForRangeDeclarationAST* ast) + -> DeclarationResult; + + [[nodiscard]] auto operator()(StructuredBindingDeclarationAST* ast) + -> DeclarationResult; +}; + +struct ASTInterpreter::TemplateParameterVisitor { + ASTInterpreter& interp; + + [[nodiscard]] auto operator()(TemplateTypeParameterAST* ast) + -> TemplateParameterResult; + + [[nodiscard]] auto operator()(NonTypeTemplateParameterAST* ast) + -> TemplateParameterResult; + + [[nodiscard]] auto operator()(TypenameTypeParameterAST* ast) + -> TemplateParameterResult; + + [[nodiscard]] auto operator()(ConstraintTypeParameterAST* ast) + -> TemplateParameterResult; +}; + +struct ASTInterpreter::FunctionBodyVisitor { + ASTInterpreter& interp; + + [[nodiscard]] auto operator()(DefaultFunctionBodyAST* ast) + -> FunctionBodyResult; + + [[nodiscard]] auto operator()(CompoundStatementFunctionBodyAST* ast) + -> FunctionBodyResult; + + [[nodiscard]] auto operator()(TryStatementFunctionBodyAST* ast) + -> FunctionBodyResult; + + [[nodiscard]] auto operator()(DeleteFunctionBodyAST* ast) + -> FunctionBodyResult; +}; + +auto ASTInterpreter::declaration(DeclarationAST* ast) -> DeclarationResult { + if (ast) return visit(DeclarationVisitor{*this}, ast); + return {}; +} + +auto ASTInterpreter::templateParameter(TemplateParameterAST* ast) + -> TemplateParameterResult { + if (ast) return visit(TemplateParameterVisitor{*this}, ast); + return {}; +} + +auto ASTInterpreter::functionBody(FunctionBodyAST* ast) -> FunctionBodyResult { + if (ast) return visit(FunctionBodyVisitor{*this}, ast); + return {}; +} + +auto ASTInterpreter::usingDeclarator(UsingDeclaratorAST* ast) + -> UsingDeclaratorResult { + if (!ast) return {}; + + auto nestedNameSpecifierResult = + nestedNameSpecifier(ast->nestedNameSpecifier); + auto unqualifiedIdResult = unqualifiedId(ast->unqualifiedId); + + return {}; +} + +auto ASTInterpreter::nestedNamespaceSpecifier(NestedNamespaceSpecifierAST* ast) + -> NestedNamespaceSpecifierResult { + if (!ast) return {}; + + return {}; +} + +auto ASTInterpreter::asmOperand(AsmOperandAST* ast) -> DeclarationResult { + auto expressionResult = expression(ast->expression); + + return {}; +} + +auto ASTInterpreter::asmQualifier(AsmQualifierAST* ast) -> DeclarationResult { + return {}; +} + +auto ASTInterpreter::asmClobber(AsmClobberAST* ast) -> DeclarationResult { + return {}; +} + +auto ASTInterpreter::asmGotoLabel(AsmGotoLabelAST* ast) -> DeclarationResult { + return {}; +} + +auto ASTInterpreter::typeConstraint(TypeConstraintAST* ast) + -> TypeConstraintResult { + if (!ast) return {}; + + auto nestedNameSpecifierResult = + nestedNameSpecifier(ast->nestedNameSpecifier); + + for (auto node : ListView{ast->templateArgumentList}) { + auto value = templateArgument(node); + } + + return {}; +} + +auto ASTInterpreter::lambdaSpecifier(LambdaSpecifierAST* ast) + -> LambdaSpecifierResult { + if (!ast) return {}; + + return {}; +} + +auto ASTInterpreter::DeclarationVisitor::operator()(SimpleDeclarationAST* ast) + -> DeclarationResult { + for (auto node : ListView{ast->attributeList}) { + auto value = interp.attributeSpecifier(node); + } + + for (auto node : ListView{ast->declSpecifierList}) { + auto value = interp.specifier(node); + } + + for (auto node : ListView{ast->initDeclaratorList}) { + auto value = interp.initDeclarator(node); + } + + auto requiresClauseResult = interp.requiresClause(ast->requiresClause); + + return {}; +} + +auto ASTInterpreter::DeclarationVisitor::operator()(AsmDeclarationAST* ast) + -> DeclarationResult { + for (auto node : ListView{ast->attributeList}) { + auto value = interp.attributeSpecifier(node); + } + + for (auto node : ListView{ast->asmQualifierList}) { + auto value = interp.asmQualifier(node); + } + + for (auto node : ListView{ast->outputOperandList}) { + auto value = interp.asmOperand(node); + } + + for (auto node : ListView{ast->inputOperandList}) { + auto value = interp.asmOperand(node); + } + + for (auto node : ListView{ast->clobberList}) { + auto value = interp.asmClobber(node); + } + + for (auto node : ListView{ast->gotoLabelList}) { + auto value = interp.asmGotoLabel(node); + } + + return {}; +} + +auto ASTInterpreter::DeclarationVisitor::operator()( + NamespaceAliasDefinitionAST* ast) -> DeclarationResult { + auto nestedNameSpecifierResult = + interp.nestedNameSpecifier(ast->nestedNameSpecifier); + auto unqualifiedIdResult = interp.unqualifiedId(ast->unqualifiedId); + + return {}; +} + +auto ASTInterpreter::DeclarationVisitor::operator()(UsingDeclarationAST* ast) + -> DeclarationResult { + for (auto node : ListView{ast->usingDeclaratorList}) { + auto value = interp.usingDeclarator(node); + } + + return {}; +} + +auto ASTInterpreter::DeclarationVisitor::operator()( + UsingEnumDeclarationAST* ast) -> DeclarationResult { + auto enumTypeSpecifierResult = interp.specifier(ast->enumTypeSpecifier); + + return {}; +} + +auto ASTInterpreter::DeclarationVisitor::operator()(UsingDirectiveAST* ast) + -> DeclarationResult { + for (auto node : ListView{ast->attributeList}) { + auto value = interp.attributeSpecifier(node); + } + + auto nestedNameSpecifierResult = + interp.nestedNameSpecifier(ast->nestedNameSpecifier); + auto unqualifiedIdResult = interp.unqualifiedId(ast->unqualifiedId); + + return {}; +} + +auto ASTInterpreter::DeclarationVisitor::operator()( + StaticAssertDeclarationAST* ast) -> DeclarationResult { + auto expressionResult = interp.expression(ast->expression); + + return {}; +} + +auto ASTInterpreter::DeclarationVisitor::operator()(AliasDeclarationAST* ast) + -> DeclarationResult { + for (auto node : ListView{ast->attributeList}) { + auto value = interp.attributeSpecifier(node); + } + + for (auto node : ListView{ast->gnuAttributeList}) { + auto value = interp.attributeSpecifier(node); + } + + auto typeIdResult = interp.typeId(ast->typeId); + + return {}; +} + +auto ASTInterpreter::DeclarationVisitor::operator()( + OpaqueEnumDeclarationAST* ast) -> DeclarationResult { + for (auto node : ListView{ast->attributeList}) { + auto value = interp.attributeSpecifier(node); + } + + auto nestedNameSpecifierResult = + interp.nestedNameSpecifier(ast->nestedNameSpecifier); + auto unqualifiedIdResult = interp.unqualifiedId(ast->unqualifiedId); + + for (auto node : ListView{ast->typeSpecifierList}) { + auto value = interp.specifier(node); + } + + return {}; +} + +auto ASTInterpreter::DeclarationVisitor::operator()(FunctionDefinitionAST* ast) + -> DeclarationResult { + for (auto node : ListView{ast->attributeList}) { + auto value = interp.attributeSpecifier(node); + } + + for (auto node : ListView{ast->declSpecifierList}) { + auto value = interp.specifier(node); + } + + auto declaratorResult = interp.declarator(ast->declarator); + auto requiresClauseResult = interp.requiresClause(ast->requiresClause); + auto functionBodyResult = interp.functionBody(ast->functionBody); + + return {}; +} + +auto ASTInterpreter::DeclarationVisitor::operator()(TemplateDeclarationAST* ast) + -> DeclarationResult { + for (auto node : ListView{ast->templateParameterList}) { + auto value = interp.templateParameter(node); + } + + auto requiresClauseResult = interp.requiresClause(ast->requiresClause); + auto declarationResult = interp.declaration(ast->declaration); + + return {}; +} + +auto ASTInterpreter::DeclarationVisitor::operator()(ConceptDefinitionAST* ast) + -> DeclarationResult { + auto expressionResult = interp.expression(ast->expression); + + return {}; +} + +auto ASTInterpreter::DeclarationVisitor::operator()(DeductionGuideAST* ast) + -> DeclarationResult { + auto explicitSpecifierResult = interp.specifier(ast->explicitSpecifier); + auto parameterDeclarationClauseResult = + interp.parameterDeclarationClause(ast->parameterDeclarationClause); + auto templateIdResult = interp.unqualifiedId(ast->templateId); + + return {}; +} + +auto ASTInterpreter::DeclarationVisitor::operator()( + ExplicitInstantiationAST* ast) -> DeclarationResult { + auto declarationResult = interp.declaration(ast->declaration); + + return {}; +} + +auto ASTInterpreter::DeclarationVisitor::operator()(ExportDeclarationAST* ast) + -> DeclarationResult { + auto declarationResult = interp.declaration(ast->declaration); + + return {}; +} + +auto ASTInterpreter::DeclarationVisitor::operator()( + ExportCompoundDeclarationAST* ast) -> DeclarationResult { + for (auto node : ListView{ast->declarationList}) { + auto value = interp.declaration(node); + } + + return {}; +} + +auto ASTInterpreter::DeclarationVisitor::operator()( + LinkageSpecificationAST* ast) -> DeclarationResult { + for (auto node : ListView{ast->declarationList}) { + auto value = interp.declaration(node); + } + + return {}; +} + +auto ASTInterpreter::DeclarationVisitor::operator()(NamespaceDefinitionAST* ast) + -> DeclarationResult { + for (auto node : ListView{ast->attributeList}) { + auto value = interp.attributeSpecifier(node); + } + + for (auto node : ListView{ast->nestedNamespaceSpecifierList}) { + auto value = interp.nestedNamespaceSpecifier(node); + } + + for (auto node : ListView{ast->extraAttributeList}) { + auto value = interp.attributeSpecifier(node); + } + + for (auto node : ListView{ast->declarationList}) { + auto value = interp.declaration(node); + } + + return {}; +} + +auto ASTInterpreter::DeclarationVisitor::operator()(EmptyDeclarationAST* ast) + -> DeclarationResult { + return {}; +} + +auto ASTInterpreter::DeclarationVisitor::operator()( + AttributeDeclarationAST* ast) -> DeclarationResult { + for (auto node : ListView{ast->attributeList}) { + auto value = interp.attributeSpecifier(node); + } + + return {}; +} + +auto ASTInterpreter::DeclarationVisitor::operator()( + ModuleImportDeclarationAST* ast) -> DeclarationResult { + auto importNameResult = interp.importName(ast->importName); + + for (auto node : ListView{ast->attributeList}) { + auto value = interp.attributeSpecifier(node); + } + + return {}; +} + +auto ASTInterpreter::DeclarationVisitor::operator()( + ParameterDeclarationAST* ast) -> DeclarationResult { + for (auto node : ListView{ast->attributeList}) { + auto value = interp.attributeSpecifier(node); + } + + for (auto node : ListView{ast->typeSpecifierList}) { + auto value = interp.specifier(node); + } + + auto declaratorResult = interp.declarator(ast->declarator); + auto expressionResult = interp.expression(ast->expression); + + return {}; +} + +auto ASTInterpreter::DeclarationVisitor::operator()(AccessDeclarationAST* ast) + -> DeclarationResult { + return {}; +} + +auto ASTInterpreter::DeclarationVisitor::operator()(ForRangeDeclarationAST* ast) + -> DeclarationResult { + return {}; +} + +auto ASTInterpreter::DeclarationVisitor::operator()( + StructuredBindingDeclarationAST* ast) -> DeclarationResult { + for (auto node : ListView{ast->attributeList}) { + auto value = interp.attributeSpecifier(node); + } + + for (auto node : ListView{ast->declSpecifierList}) { + auto value = interp.specifier(node); + } + + for (auto node : ListView{ast->bindingList}) { + auto value = interp.unqualifiedId(node); + } + + auto initializerResult = interp.expression(ast->initializer); + + return {}; +} + +auto ASTInterpreter::TemplateParameterVisitor::operator()( + TemplateTypeParameterAST* ast) -> TemplateParameterResult { + for (auto node : ListView{ast->templateParameterList}) { + auto value = interp.templateParameter(node); + } + + auto requiresClauseResult = interp.requiresClause(ast->requiresClause); + auto idExpressionResult = interp.expression(ast->idExpression); + + return {}; +} + +auto ASTInterpreter::TemplateParameterVisitor::operator()( + NonTypeTemplateParameterAST* ast) -> TemplateParameterResult { + auto declarationResult = interp.declaration(ast->declaration); + + return {}; +} + +auto ASTInterpreter::TemplateParameterVisitor::operator()( + TypenameTypeParameterAST* ast) -> TemplateParameterResult { + auto typeIdResult = interp.typeId(ast->typeId); + + return {}; +} + +auto ASTInterpreter::TemplateParameterVisitor::operator()( + ConstraintTypeParameterAST* ast) -> TemplateParameterResult { + auto typeConstraintResult = interp.typeConstraint(ast->typeConstraint); + auto typeIdResult = interp.typeId(ast->typeId); + + return {}; +} + +auto ASTInterpreter::FunctionBodyVisitor::operator()( + DefaultFunctionBodyAST* ast) -> FunctionBodyResult { + return {}; +} + +auto ASTInterpreter::FunctionBodyVisitor::operator()( + CompoundStatementFunctionBodyAST* ast) -> FunctionBodyResult { + for (auto node : ListView{ast->memInitializerList}) { + auto value = interp.memInitializer(node); + } + + auto statementResult = interp.statement(ast->statement); + + return {}; +} + +auto ASTInterpreter::FunctionBodyVisitor::operator()( + TryStatementFunctionBodyAST* ast) -> FunctionBodyResult { + for (auto node : ListView{ast->memInitializerList}) { + auto value = interp.memInitializer(node); + } + + auto statementResult = interp.statement(ast->statement); + + for (auto node : ListView{ast->handlerList}) { + auto value = interp.handler(node); + } + + return {}; +} + +auto ASTInterpreter::FunctionBodyVisitor::operator()(DeleteFunctionBodyAST* ast) + -> FunctionBodyResult { + return {}; +} + +} // namespace cxx diff --git a/src/parser/cxx/ast_interpreter_declarators.cc b/src/parser/cxx/ast_interpreter_declarators.cc new file mode 100644 index 00000000..132cae5f --- /dev/null +++ b/src/parser/cxx/ast_interpreter_declarators.cc @@ -0,0 +1,429 @@ +// Copyright (c) 2025 Roberto Raggi +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. + +#include + +// cxx +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +namespace cxx { + +struct ASTInterpreter::PtrOperatorVisitor { + ASTInterpreter& interp; + + [[nodiscard]] auto operator()(PointerOperatorAST* ast) -> PtrOperatorResult; + + [[nodiscard]] auto operator()(ReferenceOperatorAST* ast) -> PtrOperatorResult; + + [[nodiscard]] auto operator()(PtrToMemberOperatorAST* ast) + -> PtrOperatorResult; +}; + +struct ASTInterpreter::CoreDeclaratorVisitor { + ASTInterpreter& interp; + + [[nodiscard]] auto operator()(BitfieldDeclaratorAST* ast) + -> CoreDeclaratorResult; + + [[nodiscard]] auto operator()(ParameterPackAST* ast) -> CoreDeclaratorResult; + + [[nodiscard]] auto operator()(IdDeclaratorAST* ast) -> CoreDeclaratorResult; + + [[nodiscard]] auto operator()(NestedDeclaratorAST* ast) + -> CoreDeclaratorResult; +}; + +struct ASTInterpreter::DeclaratorChunkVisitor { + ASTInterpreter& interp; + + [[nodiscard]] auto operator()(FunctionDeclaratorChunkAST* ast) + -> DeclaratorChunkResult; + + [[nodiscard]] auto operator()(ArrayDeclaratorChunkAST* ast) + -> DeclaratorChunkResult; +}; + +struct ASTInterpreter::ExceptionSpecifierVisitor { + ASTInterpreter& interp; + + [[nodiscard]] auto operator()(ThrowExceptionSpecifierAST* ast) + -> ExceptionSpecifierResult; + + [[nodiscard]] auto operator()(NoexceptSpecifierAST* ast) + -> ExceptionSpecifierResult; +}; + +struct ASTInterpreter::RequirementVisitor { + ASTInterpreter& interp; + + [[nodiscard]] auto operator()(SimpleRequirementAST* ast) -> RequirementResult; + + [[nodiscard]] auto operator()(CompoundRequirementAST* ast) + -> RequirementResult; + + [[nodiscard]] auto operator()(TypeRequirementAST* ast) -> RequirementResult; + + [[nodiscard]] auto operator()(NestedRequirementAST* ast) -> RequirementResult; +}; + +struct ASTInterpreter::MemInitializerVisitor { + ASTInterpreter& interp; + + [[nodiscard]] auto operator()(ParenMemInitializerAST* ast) + -> MemInitializerResult; + + [[nodiscard]] auto operator()(BracedMemInitializerAST* ast) + -> MemInitializerResult; +}; + +struct ASTInterpreter::LambdaCaptureVisitor { + ASTInterpreter& interp; + + [[nodiscard]] auto operator()(ThisLambdaCaptureAST* ast) + -> LambdaCaptureResult; + + [[nodiscard]] auto operator()(DerefThisLambdaCaptureAST* ast) + -> LambdaCaptureResult; + + [[nodiscard]] auto operator()(SimpleLambdaCaptureAST* ast) + -> LambdaCaptureResult; + + [[nodiscard]] auto operator()(RefLambdaCaptureAST* ast) + -> LambdaCaptureResult; + + [[nodiscard]] auto operator()(RefInitLambdaCaptureAST* ast) + -> LambdaCaptureResult; + + [[nodiscard]] auto operator()(InitLambdaCaptureAST* ast) + -> LambdaCaptureResult; +}; + +auto ASTInterpreter::ptrOperator(PtrOperatorAST* ast) -> PtrOperatorResult { + if (ast) return visit(PtrOperatorVisitor{*this}, ast); + return {}; +} + +auto ASTInterpreter::coreDeclarator(CoreDeclaratorAST* ast) + -> CoreDeclaratorResult { + if (ast) return visit(CoreDeclaratorVisitor{*this}, ast); + return {}; +} + +auto ASTInterpreter::declaratorChunk(DeclaratorChunkAST* ast) + -> DeclaratorChunkResult { + if (ast) return visit(DeclaratorChunkVisitor{*this}, ast); + return {}; +} + +auto ASTInterpreter::exceptionSpecifier(ExceptionSpecifierAST* ast) + -> ExceptionSpecifierResult { + if (ast) return visit(ExceptionSpecifierVisitor{*this}, ast); + return {}; +} + +auto ASTInterpreter::requirement(RequirementAST* ast) -> RequirementResult { + if (ast) return visit(RequirementVisitor{*this}, ast); + return {}; +} + +auto ASTInterpreter::memInitializer(MemInitializerAST* ast) + -> MemInitializerResult { + if (ast) return visit(MemInitializerVisitor{*this}, ast); + return {}; +} + +auto ASTInterpreter::lambdaCapture(LambdaCaptureAST* ast) + -> LambdaCaptureResult { + if (ast) return visit(LambdaCaptureVisitor{*this}, ast); + return {}; +} + +auto ASTInterpreter::initDeclarator(InitDeclaratorAST* ast) + -> InitDeclaratorResult { + if (!ast) return {}; + + auto declaratorResult = declarator(ast->declarator); + auto requiresClauseResult = requiresClause(ast->requiresClause); + auto initializerResult = expression(ast->initializer); + + return {}; +} + +auto ASTInterpreter::declarator(DeclaratorAST* ast) -> DeclaratorResult { + if (!ast) return {}; + + for (auto node : ListView{ast->ptrOpList}) { + auto value = ptrOperator(node); + } + + auto coreDeclaratorResult = coreDeclarator(ast->coreDeclarator); + + for (auto node : ListView{ast->declaratorChunkList}) { + auto value = declaratorChunk(node); + } + + return {}; +} + +auto ASTInterpreter::requiresClause(RequiresClauseAST* ast) + -> RequiresClauseResult { + if (!ast) return {}; + + auto expressionResult = expression(ast->expression); + + return {}; +} + +auto ASTInterpreter::parameterDeclarationClause( + ParameterDeclarationClauseAST* ast) -> ParameterDeclarationClauseResult { + if (!ast) return {}; + + for (auto node : ListView{ast->parameterDeclarationList}) { + auto value = declaration(node); + } + + return {}; +} + +auto ASTInterpreter::trailingReturnType(TrailingReturnTypeAST* ast) + -> TrailingReturnTypeResult { + if (!ast) return {}; + + auto typeIdResult = typeId(ast->typeId); + + return {}; +} + +auto ASTInterpreter::PtrOperatorVisitor::operator()(PointerOperatorAST* ast) + -> PtrOperatorResult { + for (auto node : ListView{ast->attributeList}) { + auto value = interp.attributeSpecifier(node); + } + + for (auto node : ListView{ast->cvQualifierList}) { + auto value = interp.specifier(node); + } + + return {}; +} + +auto ASTInterpreter::PtrOperatorVisitor::operator()(ReferenceOperatorAST* ast) + -> PtrOperatorResult { + for (auto node : ListView{ast->attributeList}) { + auto value = interp.attributeSpecifier(node); + } + + return {}; +} + +auto ASTInterpreter::PtrOperatorVisitor::operator()(PtrToMemberOperatorAST* ast) + -> PtrOperatorResult { + auto nestedNameSpecifierResult = + interp.nestedNameSpecifier(ast->nestedNameSpecifier); + + for (auto node : ListView{ast->attributeList}) { + auto value = interp.attributeSpecifier(node); + } + + for (auto node : ListView{ast->cvQualifierList}) { + auto value = interp.specifier(node); + } + + return {}; +} + +auto ASTInterpreter::CoreDeclaratorVisitor::operator()( + BitfieldDeclaratorAST* ast) -> CoreDeclaratorResult { + auto unqualifiedIdResult = interp.unqualifiedId(ast->unqualifiedId); + auto sizeExpressionResult = interp.expression(ast->sizeExpression); + + return {}; +} + +auto ASTInterpreter::CoreDeclaratorVisitor::operator()(ParameterPackAST* ast) + -> CoreDeclaratorResult { + auto coreDeclaratorResult = interp.coreDeclarator(ast->coreDeclarator); + + return {}; +} + +auto ASTInterpreter::CoreDeclaratorVisitor::operator()(IdDeclaratorAST* ast) + -> CoreDeclaratorResult { + auto nestedNameSpecifierResult = + interp.nestedNameSpecifier(ast->nestedNameSpecifier); + auto unqualifiedIdResult = interp.unqualifiedId(ast->unqualifiedId); + + for (auto node : ListView{ast->attributeList}) { + auto value = interp.attributeSpecifier(node); + } + + return {}; +} + +auto ASTInterpreter::CoreDeclaratorVisitor::operator()(NestedDeclaratorAST* ast) + -> CoreDeclaratorResult { + auto declaratorResult = interp.declarator(ast->declarator); + + return {}; +} + +auto ASTInterpreter::DeclaratorChunkVisitor::operator()( + FunctionDeclaratorChunkAST* ast) -> DeclaratorChunkResult { + auto parameterDeclarationClauseResult = + interp.parameterDeclarationClause(ast->parameterDeclarationClause); + + for (auto node : ListView{ast->cvQualifierList}) { + auto value = interp.specifier(node); + } + + auto exceptionSpecifierResult = + interp.exceptionSpecifier(ast->exceptionSpecifier); + + for (auto node : ListView{ast->attributeList}) { + auto value = interp.attributeSpecifier(node); + } + + auto trailingReturnTypeResult = + interp.trailingReturnType(ast->trailingReturnType); + + return {}; +} + +auto ASTInterpreter::DeclaratorChunkVisitor::operator()( + ArrayDeclaratorChunkAST* ast) -> DeclaratorChunkResult { + auto expressionResult = interp.expression(ast->expression); + + for (auto node : ListView{ast->attributeList}) { + auto value = interp.attributeSpecifier(node); + } + + return {}; +} + +auto ASTInterpreter::ExceptionSpecifierVisitor::operator()( + ThrowExceptionSpecifierAST* ast) -> ExceptionSpecifierResult { + return {}; +} + +auto ASTInterpreter::ExceptionSpecifierVisitor::operator()( + NoexceptSpecifierAST* ast) -> ExceptionSpecifierResult { + auto expressionResult = interp.expression(ast->expression); + + return {}; +} + +auto ASTInterpreter::RequirementVisitor::operator()(SimpleRequirementAST* ast) + -> RequirementResult { + auto expressionResult = interp.expression(ast->expression); + + return {}; +} + +auto ASTInterpreter::RequirementVisitor::operator()(CompoundRequirementAST* ast) + -> RequirementResult { + auto expressionResult = interp.expression(ast->expression); + auto typeConstraintResult = interp.typeConstraint(ast->typeConstraint); + + return {}; +} + +auto ASTInterpreter::RequirementVisitor::operator()(TypeRequirementAST* ast) + -> RequirementResult { + auto nestedNameSpecifierResult = + interp.nestedNameSpecifier(ast->nestedNameSpecifier); + auto unqualifiedIdResult = interp.unqualifiedId(ast->unqualifiedId); + + return {}; +} + +auto ASTInterpreter::RequirementVisitor::operator()(NestedRequirementAST* ast) + -> RequirementResult { + auto expressionResult = interp.expression(ast->expression); + + return {}; +} + +auto ASTInterpreter::MemInitializerVisitor::operator()( + ParenMemInitializerAST* ast) -> MemInitializerResult { + auto nestedNameSpecifierResult = + interp.nestedNameSpecifier(ast->nestedNameSpecifier); + auto unqualifiedIdResult = interp.unqualifiedId(ast->unqualifiedId); + + for (auto node : ListView{ast->expressionList}) { + auto value = interp.expression(node); + } + + return {}; +} + +auto ASTInterpreter::MemInitializerVisitor::operator()( + BracedMemInitializerAST* ast) -> MemInitializerResult { + auto nestedNameSpecifierResult = + interp.nestedNameSpecifier(ast->nestedNameSpecifier); + auto unqualifiedIdResult = interp.unqualifiedId(ast->unqualifiedId); + auto bracedInitListResult = interp.expression(ast->bracedInitList); + + return {}; +} + +auto ASTInterpreter::LambdaCaptureVisitor::operator()(ThisLambdaCaptureAST* ast) + -> LambdaCaptureResult { + return {}; +} + +auto ASTInterpreter::LambdaCaptureVisitor::operator()( + DerefThisLambdaCaptureAST* ast) -> LambdaCaptureResult { + return {}; +} + +auto ASTInterpreter::LambdaCaptureVisitor::operator()( + SimpleLambdaCaptureAST* ast) -> LambdaCaptureResult { + return {}; +} + +auto ASTInterpreter::LambdaCaptureVisitor::operator()(RefLambdaCaptureAST* ast) + -> LambdaCaptureResult { + return {}; +} + +auto ASTInterpreter::LambdaCaptureVisitor::operator()( + RefInitLambdaCaptureAST* ast) -> LambdaCaptureResult { + auto initializerResult = interp.expression(ast->initializer); + + return {}; +} + +auto ASTInterpreter::LambdaCaptureVisitor::operator()(InitLambdaCaptureAST* ast) + -> LambdaCaptureResult { + auto initializerResult = interp.expression(ast->initializer); + + return {}; +} + +} // namespace cxx diff --git a/src/parser/cxx/ast_interpreter_expressions.cc b/src/parser/cxx/ast_interpreter_expressions.cc new file mode 100644 index 00000000..4761763b --- /dev/null +++ b/src/parser/cxx/ast_interpreter_expressions.cc @@ -0,0 +1,1471 @@ +// Copyright (c) 2025 Roberto Raggi +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. + +#include + +// cxx +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +namespace cxx { + +struct ASTInterpreter::ExpressionVisitor { + ASTInterpreter& interp; + + [[nodiscard]] auto unit() -> TranslationUnit* { return interp.unit_; } + + [[nodiscard]] auto control() -> Control* { return interp.control(); } + + [[nodiscard]] auto memoryLayout() -> MemoryLayout* { + return control()->memoryLayout(); + } + + [[nodiscard]] auto evaluate(ExpressionAST* ast) -> ExpressionResult { + return interp.expression(ast); + } + + [[nodiscard]] auto toBool(const ConstValue& value) -> bool { + return interp.toBool(value).value_or(false); + } + + [[nodiscard]] auto toInt(const ConstValue& value) -> std::intmax_t { + return interp.toInt(value).value_or(0); + } + + [[nodiscard]] auto toInt32(const ConstValue& value) -> std::int32_t { + return static_cast(toInt(value)); + } + + [[nodiscard]] auto toInt64(const ConstValue& value) -> std::int64_t { + return static_cast(toInt(value)); + } + + [[nodiscard]] auto toUInt(const ConstValue& value) -> std::uintmax_t { + return interp.toUInt(value).value_or(0); + } + + [[nodiscard]] auto toUInt32(const ConstValue& value) -> std::uint32_t { + return static_cast(toUInt(value)); + } + + [[nodiscard]] auto toUInt64(const ConstValue& value) -> std::uint64_t { + return static_cast(toUInt(value)); + } + + [[nodiscard]] auto toFloat(const ConstValue& value) -> float { + return interp.toFloat(value).value_or(0.0f); + } + + [[nodiscard]] auto toDouble(const ConstValue& value) -> double { + return interp.toDouble(value).value_or(0.0); + } + + [[nodiscard]] auto toValue(std::uintmax_t value) -> ConstValue { + return ConstValue(std::bit_cast(value)); + } + + auto star_op(BinaryExpressionAST* ast, const ExpressionResult& left, + const ExpressionResult& right) -> ExpressionResult { + const auto type = ast->leftExpression->type; + const auto sz = memoryLayout()->sizeOf(type); + + if (control()->is_floating_point(type)) { + return toDouble(*left) * toDouble(*right); + } + + if (control()->is_unsigned(type)) { + if (sz <= 4) return toValue(toUInt32(*left) * toUInt32(*right)); + return toValue(toUInt64(*left) * toUInt64(*right)); + } + + if (sz <= 4) return toValue(toInt32(*left) * toInt32(*right)); + return toValue(toInt64(*left) * toInt64(*right)); + } + + auto slash_op(BinaryExpressionAST* ast, const ExpressionResult& left, + const ExpressionResult& right) -> ExpressionResult { + const auto type = ast->leftExpression->type; + const auto sz = memoryLayout()->sizeOf(type); + + if (control()->is_floating_point(type)) { + auto l = toDouble(*left); + auto r = toDouble(*right); + if (r == 0.0) return std::nullopt; + return l / r; + } + + if (control()->is_unsigned(type)) { + if (sz <= 4) { + auto l = toUInt32(*left); + auto r = toUInt32(*right); + if (r == 0) return std::nullopt; + return toValue(l / r); + } + + auto l = toUInt64(*left); + auto r = toUInt64(*right); + if (r == 0) return std::nullopt; + return toValue(l / r); + } + + if (sz <= 4) { + auto l = toInt32(*left); + auto r = toInt32(*right); + if (r == 0) return std::nullopt; + return toValue(l / r); + } + + auto l = toInt64(*left); + auto r = toInt64(*right); + if (r == 0) return std::nullopt; + return toValue(l / r); + } + + auto percent_op(BinaryExpressionAST* ast, const ExpressionResult& left, + const ExpressionResult& right) -> ExpressionResult { + const auto type = ast->leftExpression->type; + const auto sz = memoryLayout()->sizeOf(type); + + if (control()->is_unsigned(type)) { + if (sz <= 4) { + auto l = toUInt32(*left); + auto r = toUInt32(*right); + if (r == 0) return std::nullopt; + return toValue(l % r); + } + + auto l = toUInt64(*left); + auto r = toUInt64(*right); + if (r == 0) return std::nullopt; + return toValue(l % r); + } + + if (sz <= 4) { + auto l = toInt32(*left); + auto r = toInt32(*right); + if (r == 0) return std::nullopt; + return toValue(l % r); + } + + auto l = toInt64(*left); + auto r = toInt64(*right); + if (r == 0) return std::nullopt; + return toValue(l % r); + } + + auto plus_op(BinaryExpressionAST* ast, const ExpressionResult& left, + const ExpressionResult& right) -> ExpressionResult { + const auto type = ast->leftExpression->type; + const auto sz = memoryLayout()->sizeOf(type); + + if (control()->is_floating_point(type)) { + return toDouble(*left) + toDouble(*right); + } + + if (control()->is_unsigned(type)) { + if (sz <= 4) return toValue(toUInt32(*left) + toUInt32(*right)); + return toValue(toUInt64(*left) + toUInt64(*right)); + } + + if (sz <= 4) return toValue(toInt32(*left) + toInt32(*right)); + return toValue(toInt64(*left) + toInt64(*right)); + } + + auto minus_op(BinaryExpressionAST* ast, const ExpressionResult& left, + const ExpressionResult& right) -> ExpressionResult { + const auto type = ast->leftExpression->type; + const auto sz = memoryLayout()->sizeOf(type); + + if (control()->is_floating_point(type)) { + return toDouble(*left) - toDouble(*right); + } + + if (control()->is_unsigned(type)) { + if (sz <= 4) return toValue(toUInt32(*left) - toUInt32(*right)); + return toValue(toUInt64(*left) - toUInt64(*right)); + } + + if (sz <= 4) return toValue(toInt32(*left) - toInt32(*right)); + return toValue(toInt64(*left) - toInt64(*right)); + } + + auto less_less_op(BinaryExpressionAST* ast, const ExpressionResult& left, + const ExpressionResult& right) -> ExpressionResult { + const auto type = ast->leftExpression->type; + const auto sz = memoryLayout()->sizeOf(type); + + if (control()->is_unsigned(type)) { + if (sz <= 4) return toValue(toUInt32(*left) << toUInt32(*right)); + return toValue(toUInt64(*left) << toUInt64(*right)); + } + + if (sz <= 4) return toValue(toInt32(*left) << toInt32(*right)); + return toValue(toInt64(*left) << toInt64(*right)); + } + + auto greater_greater_op(BinaryExpressionAST* ast, + const ExpressionResult& left, + const ExpressionResult& right) -> ExpressionResult { + const auto type = ast->leftExpression->type; + const auto sz = memoryLayout()->sizeOf(type); + + if (control()->is_unsigned(type)) { + if (sz <= 4) return toValue(toUInt32(*left) >> toUInt32(*right)); + return toValue(toUInt64(*left) >> toUInt64(*right)); + } + + if (sz <= 4) return toValue(toInt32(*left) >> toInt32(*right)); + return toValue(toInt64(*left) >> toInt64(*right)); + } + + auto less_equal_greater_op(BinaryExpressionAST* ast, + const ExpressionResult& left, + const ExpressionResult& right) + -> ExpressionResult { + auto convert = [](std::partial_ordering cmp) -> int { + if (cmp < 0) return -1; + if (cmp > 0) return 1; + return 0; + }; + + const auto type = ast->leftExpression->type; + const auto sz = memoryLayout()->sizeOf(type); + + if (control()->is_floating_point(type)) + return convert(toDouble(*left) <=> toDouble(*right)); + + if (control()->is_unsigned(type)) { + if (sz <= 4) return convert(toUInt32(*left) <=> toUInt32(*right)); + return convert(toUInt64(*left) <=> toUInt64(*right)); + } + + if (sz <= 4) return convert(toInt32(*left) <=> toInt32(*right)); + return convert(toInt64(*left) <=> toInt64(*right)); + } + + auto less_equal_op(BinaryExpressionAST* ast, const ExpressionResult& left, + const ExpressionResult& right) -> ExpressionResult { + const auto type = ast->leftExpression->type; + const auto sz = memoryLayout()->sizeOf(type); + + if (control()->is_floating_point(type)) + return toDouble(*left) <= toDouble(*right); + + if (control()->is_unsigned(type)) { + if (sz <= 4) return toUInt(*left) <= toUInt(*right); + return toUInt64(*left) <= toUInt64(*right); + } + + if (sz <= 4) return toInt(*left) <= toInt(*right); + return toInt64(*left) <= toInt64(*right); + } + + auto greater_equal_op(BinaryExpressionAST* ast, const ExpressionResult& left, + const ExpressionResult& right) -> ExpressionResult { + const auto type = ast->leftExpression->type; + const auto sz = memoryLayout()->sizeOf(type); + + if (control()->is_floating_point(type)) + return toDouble(*left) >= toDouble(*right); + + if (control()->is_unsigned(type)) { + if (sz <= 4) return toUInt(*left) >= toUInt(*right); + return toUInt64(*left) >= toUInt64(*right); + } + + if (sz <= 4) return toInt(*left) >= toInt(*right); + return toInt64(*left) >= toInt64(*right); + } + + auto less_op(BinaryExpressionAST* ast, const ExpressionResult& left, + const ExpressionResult& right) -> ExpressionResult { + const auto type = ast->leftExpression->type; + const auto sz = memoryLayout()->sizeOf(type); + + if (control()->is_floating_point(type)) + return toDouble(*left) < toDouble(*right); + + if (control()->is_unsigned(type)) { + if (sz <= 4) return toUInt(*left) < toUInt(*right); + return toUInt64(*left) < toUInt64(*right); + } + + if (sz <= 4) return toInt(*left) < toInt(*right); + return toInt64(*left) < toInt64(*right); + } + + auto greater_op(BinaryExpressionAST* ast, const ExpressionResult& left, + const ExpressionResult& right) -> ExpressionResult { + const auto type = ast->leftExpression->type; + const auto sz = memoryLayout()->sizeOf(type); + + if (control()->is_floating_point(type)) + return toDouble(*left) > toDouble(*right); + + if (control()->is_unsigned(type)) { + if (sz <= 4) return toUInt(*left) > toUInt(*right); + return toUInt64(*left) > toUInt64(*right); + } + + if (sz <= 4) return toInt(*left) > toInt(*right); + return toInt64(*left) > toInt64(*right); + } + + auto equal_equal_op(BinaryExpressionAST* ast, const ExpressionResult& left, + const ExpressionResult& right) -> ExpressionResult { + const auto type = ast->leftExpression->type; + const auto sz = memoryLayout()->sizeOf(type); + + if (control()->is_floating_point(type)) + return toDouble(*left) == toDouble(*right); + + if (control()->is_unsigned(type)) { + if (sz <= 4) return toUInt(*left) == toUInt(*right); + return toUInt64(*left) == toUInt64(*right); + } + + if (sz <= 4) return toInt(*left) == toInt(*right); + return toInt64(*left) == toInt64(*right); + } + + auto exclaim_equal_op(BinaryExpressionAST* ast, const ExpressionResult& left, + const ExpressionResult& right) -> ExpressionResult { + const auto type = ast->leftExpression->type; + const auto sz = memoryLayout()->sizeOf(type); + + if (control()->is_floating_point(type)) + return toDouble(*left) != toDouble(*right); + + if (control()->is_unsigned(type)) { + if (sz <= 4) return toUInt(*left) != toUInt(*right); + return toUInt64(*left) != toUInt64(*right); + } + + if (sz <= 4) return toInt(*left) != toInt(*right); + return toInt64(*left) != toInt64(*right); + } + + auto amp_op(BinaryExpressionAST* ast, const ExpressionResult& left, + const ExpressionResult& right) -> ExpressionResult { + return toInt(*left) & toInt(*right); + } + + auto caret_op(BinaryExpressionAST* ast, const ExpressionResult& left, + const ExpressionResult& right) -> ExpressionResult { + return toInt(*left) ^ toInt(*right); + } + + auto bar_op(BinaryExpressionAST* ast, const ExpressionResult& left, + const ExpressionResult& right) -> ExpressionResult { + return toInt(*left) | toInt(*right); + } + + auto amp_amp_op(BinaryExpressionAST* ast, const ExpressionResult& left, + const ExpressionResult& right) -> ExpressionResult { + return toBool(*left) && toBool(*right); + } + + auto bar_bar_op(BinaryExpressionAST* ast, const ExpressionResult& left, + const ExpressionResult& right) -> ExpressionResult { + return toBool(*left) || toBool(*right); + } + + auto comma_op(BinaryExpressionAST* ast, const ExpressionResult& left, + const ExpressionResult& right) -> ExpressionResult { + // Comma operator returns the right operand + return right; + } + + [[nodiscard]] auto operator()(CharLiteralExpressionAST* ast) + -> ExpressionResult; + + [[nodiscard]] auto operator()(BoolLiteralExpressionAST* ast) + -> ExpressionResult; + + [[nodiscard]] auto operator()(IntLiteralExpressionAST* ast) + -> ExpressionResult; + + [[nodiscard]] auto operator()(FloatLiteralExpressionAST* ast) + -> ExpressionResult; + + [[nodiscard]] auto operator()(NullptrLiteralExpressionAST* ast) + -> ExpressionResult; + + [[nodiscard]] auto operator()(StringLiteralExpressionAST* ast) + -> ExpressionResult; + + [[nodiscard]] auto operator()(UserDefinedStringLiteralExpressionAST* ast) + -> ExpressionResult; + + [[nodiscard]] auto operator()(ObjectLiteralExpressionAST* ast) + -> ExpressionResult; + + [[nodiscard]] auto operator()(ThisExpressionAST* ast) -> ExpressionResult; + + [[nodiscard]] auto operator()(GenericSelectionExpressionAST* ast) + -> ExpressionResult; + + [[nodiscard]] auto operator()(NestedStatementExpressionAST* ast) + -> ExpressionResult; + + [[nodiscard]] auto operator()(NestedExpressionAST* ast) -> ExpressionResult; + + [[nodiscard]] auto operator()(IdExpressionAST* ast) -> ExpressionResult; + + [[nodiscard]] auto operator()(LambdaExpressionAST* ast) -> ExpressionResult; + + [[nodiscard]] auto operator()(FoldExpressionAST* ast) -> ExpressionResult; + + [[nodiscard]] auto operator()(RightFoldExpressionAST* ast) + -> ExpressionResult; + + [[nodiscard]] auto operator()(LeftFoldExpressionAST* ast) -> ExpressionResult; + + [[nodiscard]] auto operator()(RequiresExpressionAST* ast) -> ExpressionResult; + + [[nodiscard]] auto operator()(VaArgExpressionAST* ast) -> ExpressionResult; + + [[nodiscard]] auto operator()(SubscriptExpressionAST* ast) + -> ExpressionResult; + + [[nodiscard]] auto operator()(CallExpressionAST* ast) -> ExpressionResult; + + [[nodiscard]] auto operator()(TypeConstructionAST* ast) -> ExpressionResult; + + [[nodiscard]] auto operator()(BracedTypeConstructionAST* ast) + -> ExpressionResult; + + [[nodiscard]] auto operator()(SpliceMemberExpressionAST* ast) + -> ExpressionResult; + + [[nodiscard]] auto operator()(MemberExpressionAST* ast) -> ExpressionResult; + + [[nodiscard]] auto operator()(PostIncrExpressionAST* ast) -> ExpressionResult; + + [[nodiscard]] auto operator()(CppCastExpressionAST* ast) -> ExpressionResult; + + [[nodiscard]] auto operator()(BuiltinBitCastExpressionAST* ast) + -> ExpressionResult; + + [[nodiscard]] auto operator()(BuiltinOffsetofExpressionAST* ast) + -> ExpressionResult; + + [[nodiscard]] auto operator()(TypeidExpressionAST* ast) -> ExpressionResult; + + [[nodiscard]] auto operator()(TypeidOfTypeExpressionAST* ast) + -> ExpressionResult; + + [[nodiscard]] auto operator()(SpliceExpressionAST* ast) -> ExpressionResult; + + [[nodiscard]] auto operator()(GlobalScopeReflectExpressionAST* ast) + -> ExpressionResult; + + [[nodiscard]] auto operator()(NamespaceReflectExpressionAST* ast) + -> ExpressionResult; + + [[nodiscard]] auto operator()(TypeIdReflectExpressionAST* ast) + -> ExpressionResult; + + [[nodiscard]] auto operator()(ReflectExpressionAST* ast) -> ExpressionResult; + + [[nodiscard]] auto operator()(LabelAddressExpressionAST* ast) + -> ExpressionResult; + + [[nodiscard]] auto operator()(UnaryExpressionAST* ast) -> ExpressionResult; + + [[nodiscard]] auto operator()(AwaitExpressionAST* ast) -> ExpressionResult; + + [[nodiscard]] auto operator()(SizeofExpressionAST* ast) -> ExpressionResult; + + [[nodiscard]] auto operator()(SizeofTypeExpressionAST* ast) + -> ExpressionResult; + + [[nodiscard]] auto operator()(SizeofPackExpressionAST* ast) + -> ExpressionResult; + + [[nodiscard]] auto operator()(AlignofTypeExpressionAST* ast) + -> ExpressionResult; + + [[nodiscard]] auto operator()(AlignofExpressionAST* ast) -> ExpressionResult; + + [[nodiscard]] auto operator()(NoexceptExpressionAST* ast) -> ExpressionResult; + + [[nodiscard]] auto operator()(NewExpressionAST* ast) -> ExpressionResult; + + [[nodiscard]] auto operator()(DeleteExpressionAST* ast) -> ExpressionResult; + + [[nodiscard]] auto operator()(CastExpressionAST* ast) -> ExpressionResult; + + [[nodiscard]] auto operator()(ImplicitCastExpressionAST* ast) + -> ExpressionResult; + + [[nodiscard]] auto operator()(BinaryExpressionAST* ast) -> ExpressionResult; + + [[nodiscard]] auto operator()(ConditionalExpressionAST* ast) + -> ExpressionResult; + + [[nodiscard]] auto operator()(YieldExpressionAST* ast) -> ExpressionResult; + + [[nodiscard]] auto operator()(ThrowExpressionAST* ast) -> ExpressionResult; + + [[nodiscard]] auto operator()(AssignmentExpressionAST* ast) + -> ExpressionResult; + + [[nodiscard]] auto operator()(CompoundAssignmentExpressionAST* ast) + -> ExpressionResult; + + [[nodiscard]] auto operator()(PackExpansionExpressionAST* ast) + -> ExpressionResult; + + [[nodiscard]] auto operator()(DesignatedInitializerClauseAST* ast) + -> ExpressionResult; + + [[nodiscard]] auto operator()(TypeTraitExpressionAST* ast) + -> ExpressionResult; + + [[nodiscard]] auto operator()(ConditionExpressionAST* ast) + -> ExpressionResult; + + [[nodiscard]] auto operator()(EqualInitializerAST* ast) -> ExpressionResult; + + [[nodiscard]] auto operator()(BracedInitListAST* ast) -> ExpressionResult; + + [[nodiscard]] auto operator()(ParenInitializerAST* ast) -> ExpressionResult; +}; + +struct ASTInterpreter::NewInitializerVisitor { + ASTInterpreter& interp; + + [[nodiscard]] auto operator()(NewParenInitializerAST* ast) + -> NewInitializerResult; + + [[nodiscard]] auto operator()(NewBracedInitializerAST* ast) + -> NewInitializerResult; +}; + +auto ASTInterpreter::expression(ExpressionAST* ast) -> ExpressionResult { + if (ast) return visit(ExpressionVisitor{*this}, ast); + return ExpressionResult{std::nullopt}; +} + +auto ASTInterpreter::newPlacement(NewPlacementAST* ast) -> NewPlacementResult { + if (!ast) return {}; + + for (auto node : ListView{ast->expressionList}) { + auto value = expression(node); + } + + return {}; +} + +auto ASTInterpreter::newInitializer(NewInitializerAST* ast) + -> NewInitializerResult { + if (ast) return visit(NewInitializerVisitor{*this}, ast); + return {}; +} + +auto ASTInterpreter::ExpressionVisitor::operator()( + CharLiteralExpressionAST* ast) -> ExpressionResult { + return ConstValue(ast->literal->charValue()); +} + +auto ASTInterpreter::ExpressionVisitor::operator()( + BoolLiteralExpressionAST* ast) -> ExpressionResult { + return ConstValue(ast->isTrue); +} + +auto ASTInterpreter::ExpressionVisitor::operator()(IntLiteralExpressionAST* ast) + -> ExpressionResult { + const auto value = static_cast(ast->literal->integerValue()); + return ExpressionResult{std::bit_cast(value)}; +} + +auto ASTInterpreter::ExpressionVisitor::operator()( + FloatLiteralExpressionAST* ast) -> ExpressionResult { + return ConstValue(ast->literal->floatValue()); +} + +auto ASTInterpreter::ExpressionVisitor::operator()( + NullptrLiteralExpressionAST* ast) -> ExpressionResult { + return ConstValue{std::intmax_t(0)}; +} + +auto ASTInterpreter::ExpressionVisitor::operator()( + StringLiteralExpressionAST* ast) -> ExpressionResult { + return ConstValue(ast->literal); +} + +auto ASTInterpreter::ExpressionVisitor::operator()( + UserDefinedStringLiteralExpressionAST* ast) -> ExpressionResult { + return ConstValue(ast->literal); +} + +auto ASTInterpreter::ExpressionVisitor::operator()( + ObjectLiteralExpressionAST* ast) -> ExpressionResult { + return std::nullopt; +} + +auto ASTInterpreter::ExpressionVisitor::operator()(ThisExpressionAST* ast) + -> ExpressionResult { + return std::nullopt; +} + +auto ASTInterpreter::ExpressionVisitor::operator()( + GenericSelectionExpressionAST* ast) -> ExpressionResult { + if (ast->matchedAssocIndex == -1) return std::nullopt; + + GenericAssociationAST* assoc = nullptr; + int index = 0; + for (auto assocNode : ListView{ast->genericAssociationList}) { + if (index == ast->matchedAssocIndex) { + assoc = assocNode; + break; + } + ++index; + } + + if (auto def = ast_cast(assoc)) { + return interp.expression(def->expression); + } + + if (auto entry = ast_cast(assoc)) { + return interp.expression(entry->expression); + } + + return std::nullopt; +} + +auto ASTInterpreter::ExpressionVisitor::operator()(NestedExpressionAST* ast) + -> ExpressionResult { + if (ast->expression) { + return evaluate(ast->expression); + } + return std::nullopt; +} + +auto ASTInterpreter::ExpressionVisitor::operator()( + NestedStatementExpressionAST* ast) -> ExpressionResult { + return std::nullopt; +} + +auto ASTInterpreter::ExpressionVisitor::operator()(IdExpressionAST* ast) + -> ExpressionResult { + auto nestedNameSpecifierResult = + interp.nestedNameSpecifier(ast->nestedNameSpecifier); + auto unqualifiedIdResult = interp.unqualifiedId(ast->unqualifiedId); + + if (auto enumerator = symbol_cast(ast->symbol)) { + return enumerator->value(); + } + + if (auto var = symbol_cast(ast->symbol)) { + return var->constValue(); + } + + return std::nullopt; +} + +auto ASTInterpreter::ExpressionVisitor::operator()(LambdaExpressionAST* ast) + -> ExpressionResult { + for (auto node : ListView{ast->captureList}) { + auto value = interp.lambdaCapture(node); + } + + for (auto node : ListView{ast->templateParameterList}) { + auto value = interp.templateParameter(node); + } + + auto templateRequiresClauseResult = + interp.requiresClause(ast->templateRequiresClause); + + auto parameterDeclarationClauseResult = + interp.parameterDeclarationClause(ast->parameterDeclarationClause); + + for (auto node : ListView{ast->gnuAtributeList}) { + auto value = interp.attributeSpecifier(node); + } + + for (auto node : ListView{ast->lambdaSpecifierList}) { + auto value = interp.lambdaSpecifier(node); + } + + auto exceptionSpecifierResult = + interp.exceptionSpecifier(ast->exceptionSpecifier); + + for (auto node : ListView{ast->attributeList}) { + auto value = interp.attributeSpecifier(node); + } + + auto trailingReturnTypeResult = + interp.trailingReturnType(ast->trailingReturnType); + auto requiresClauseResult = interp.requiresClause(ast->requiresClause); + auto statementResult = interp.statement(ast->statement); + + return ExpressionResult{std::nullopt}; +} + +auto ASTInterpreter::ExpressionVisitor::operator()(FoldExpressionAST* ast) + -> ExpressionResult { + auto leftExpressionResult = interp.expression(ast->leftExpression); + auto rightExpressionResult = interp.expression(ast->rightExpression); + + return ExpressionResult{std::nullopt}; +} + +auto ASTInterpreter::ExpressionVisitor::operator()(RightFoldExpressionAST* ast) + -> ExpressionResult { + auto expressionResult = interp.expression(ast->expression); + + return ExpressionResult{std::nullopt}; +} + +auto ASTInterpreter::ExpressionVisitor::operator()(LeftFoldExpressionAST* ast) + -> ExpressionResult { + auto expressionResult = interp.expression(ast->expression); + + return ExpressionResult{std::nullopt}; +} + +auto ASTInterpreter::ExpressionVisitor::operator()(RequiresExpressionAST* ast) + -> ExpressionResult { + auto parameterDeclarationClauseResult = + interp.parameterDeclarationClause(ast->parameterDeclarationClause); + + for (auto node : ListView{ast->requirementList}) { + auto value = interp.requirement(node); + } + + return ExpressionResult{std::nullopt}; +} + +auto ASTInterpreter::ExpressionVisitor::operator()(VaArgExpressionAST* ast) + -> ExpressionResult { + auto expressionResult = interp.expression(ast->expression); + auto typeIdResult = interp.typeId(ast->typeId); + + return ExpressionResult{std::nullopt}; +} + +auto ASTInterpreter::ExpressionVisitor::operator()(SubscriptExpressionAST* ast) + -> ExpressionResult { + auto baseExpressionResult = interp.expression(ast->baseExpression); + auto indexExpressionResult = interp.expression(ast->indexExpression); + + return ExpressionResult{std::nullopt}; +} + +auto ASTInterpreter::ExpressionVisitor::operator()(CallExpressionAST* ast) + -> ExpressionResult { + auto baseExpressionResult = interp.expression(ast->baseExpression); + + for (auto node : ListView{ast->expressionList}) { + auto value = interp.expression(node); + } + + return ExpressionResult{std::nullopt}; +} + +auto ASTInterpreter::ExpressionVisitor::operator()(TypeConstructionAST* ast) + -> ExpressionResult { + auto typeSpecifierResult = interp.specifier(ast->typeSpecifier); + + for (auto node : ListView{ast->expressionList}) { + auto value = interp.expression(node); + } + + return ExpressionResult{std::nullopt}; +} + +auto ASTInterpreter::ExpressionVisitor::operator()( + BracedTypeConstructionAST* ast) -> ExpressionResult { + auto typeSpecifierResult = interp.specifier(ast->typeSpecifier); + auto bracedInitListResult = interp.expression(ast->bracedInitList); + + return ExpressionResult{std::nullopt}; +} + +auto ASTInterpreter::ExpressionVisitor::operator()( + SpliceMemberExpressionAST* ast) -> ExpressionResult { + auto baseExpressionResult = interp.expression(ast->baseExpression); + auto splicerResult = interp.splicer(ast->splicer); + + return ExpressionResult{std::nullopt}; +} + +auto ASTInterpreter::ExpressionVisitor::operator()(MemberExpressionAST* ast) + -> ExpressionResult { + auto baseExpressionResult = interp.expression(ast->baseExpression); + auto nestedNameSpecifierResult = + interp.nestedNameSpecifier(ast->nestedNameSpecifier); + auto unqualifiedIdResult = interp.unqualifiedId(ast->unqualifiedId); + + return ExpressionResult{std::nullopt}; +} + +auto ASTInterpreter::ExpressionVisitor::operator()(PostIncrExpressionAST* ast) + -> ExpressionResult { + auto baseExpressionResult = interp.expression(ast->baseExpression); + + return ExpressionResult{std::nullopt}; +} + +auto ASTInterpreter::ExpressionVisitor::operator()(CppCastExpressionAST* ast) + -> ExpressionResult { + auto typeIdResult = interp.typeId(ast->typeId); + auto expressionResult = interp.expression(ast->expression); + + return ExpressionResult{std::nullopt}; +} + +auto ASTInterpreter::ExpressionVisitor::operator()( + BuiltinBitCastExpressionAST* ast) -> ExpressionResult { + auto typeIdResult = interp.typeId(ast->typeId); + auto expressionResult = interp.expression(ast->expression); + + return ExpressionResult{std::nullopt}; +} + +auto ASTInterpreter::ExpressionVisitor::operator()( + BuiltinOffsetofExpressionAST* ast) -> ExpressionResult { + auto typeIdResult = interp.typeId(ast->typeId); + + if (ast->symbol) return ast->symbol->offset(); + + return std::nullopt; +} + +auto ASTInterpreter::ExpressionVisitor::operator()(TypeidExpressionAST* ast) + -> ExpressionResult { + auto expressionResult = interp.expression(ast->expression); + + return ExpressionResult{std::nullopt}; +} + +auto ASTInterpreter::ExpressionVisitor::operator()( + TypeidOfTypeExpressionAST* ast) -> ExpressionResult { + auto typeIdResult = interp.typeId(ast->typeId); + + return ExpressionResult{std::nullopt}; +} + +auto ASTInterpreter::ExpressionVisitor::operator()(SpliceExpressionAST* ast) + -> ExpressionResult { + auto splicerResult = interp.splicer(ast->splicer); + if (!splicerResult.has_value()) return std::nullopt; + + auto metaPtr = std::get_if>(&splicerResult.value()); + if (!metaPtr) return std::nullopt; + + auto meta = *metaPtr; + + auto constExprPtr = std::get_if(&meta->value); + if (!constExprPtr) return std::nullopt; + + return constExprPtr->value; +} + +auto ASTInterpreter::ExpressionVisitor::operator()( + GlobalScopeReflectExpressionAST* ast) -> ExpressionResult { + return ExpressionResult{std::nullopt}; +} + +auto ASTInterpreter::ExpressionVisitor::operator()( + NamespaceReflectExpressionAST* ast) -> ExpressionResult { + return ExpressionResult{std::nullopt}; +} + +auto ASTInterpreter::ExpressionVisitor::operator()( + TypeIdReflectExpressionAST* ast) -> ExpressionResult { + if (!ast->typeId) return std::nullopt; + if (!ast->typeId->type) return std::nullopt; + + auto meta = std::make_shared(ast->typeId->type); + + return ConstValue{meta}; +} + +auto ASTInterpreter::ExpressionVisitor::operator()(ReflectExpressionAST* ast) + -> ExpressionResult { + auto expressionResult = interp.expression(ast->expression); + + if (expressionResult.has_value()) { + auto meta = std::make_shared(Meta::ConstExpr{ + .expression = ast->expression, .value = expressionResult.value()}); + return meta; + } + + return ExpressionResult{std::nullopt}; +} + +auto ASTInterpreter::ExpressionVisitor::operator()( + LabelAddressExpressionAST* ast) -> ExpressionResult { + return ExpressionResult{std::nullopt}; +} + +auto ASTInterpreter::ExpressionVisitor::operator()(UnaryExpressionAST* ast) + -> ExpressionResult { + auto expressionResult = interp.expression(ast->expression); + + return ExpressionResult{std::nullopt}; +} + +auto ASTInterpreter::ExpressionVisitor::operator()(AwaitExpressionAST* ast) + -> ExpressionResult { + auto expressionResult = interp.expression(ast->expression); + + return ExpressionResult{std::nullopt}; +} + +auto ASTInterpreter::ExpressionVisitor::operator()(SizeofExpressionAST* ast) + -> ExpressionResult { + if (!ast->expression || !ast->expression->type) return std::nullopt; + auto size = memoryLayout()->sizeOf(ast->expression->type); + if (!size.has_value()) return std::nullopt; + return ExpressionResult( + std::bit_cast(static_cast(*size))); +} + +auto ASTInterpreter::ExpressionVisitor::operator()(SizeofTypeExpressionAST* ast) + -> ExpressionResult { + if (!ast->typeId || !ast->typeId->type) return std::nullopt; + auto size = memoryLayout()->sizeOf(ast->typeId->type); + if (!size.has_value()) return std::nullopt; + return ExpressionResult( + std::bit_cast(static_cast(*size))); +} + +auto ASTInterpreter::ExpressionVisitor::operator()(SizeofPackExpressionAST* ast) + -> ExpressionResult { + return ExpressionResult{std::nullopt}; +} + +auto ASTInterpreter::ExpressionVisitor::operator()( + AlignofTypeExpressionAST* ast) -> ExpressionResult { + if (!ast->typeId || !ast->typeId->type) return std::nullopt; + auto size = memoryLayout()->alignmentOf(ast->typeId->type); + if (!size.has_value()) return std::nullopt; + return ExpressionResult( + std::bit_cast(static_cast(*size))); +} + +auto ASTInterpreter::ExpressionVisitor::operator()(AlignofExpressionAST* ast) + -> ExpressionResult { + auto expressionResult = interp.expression(ast->expression); + + if (!ast->expression || !ast->expression->type) return std::nullopt; + auto size = memoryLayout()->alignmentOf(ast->expression->type); + if (!size.has_value()) return std::nullopt; + return ExpressionResult( + std::bit_cast(static_cast(*size))); +} + +auto ASTInterpreter::ExpressionVisitor::operator()(NoexceptExpressionAST* ast) + -> ExpressionResult { + auto expressionResult = interp.expression(ast->expression); + + return ExpressionResult{std::nullopt}; +} + +auto ASTInterpreter::ExpressionVisitor::operator()(NewExpressionAST* ast) + -> ExpressionResult { + auto newPlacementResult = interp.newPlacement(ast->newPlacement); + + for (auto node : ListView{ast->typeSpecifierList}) { + auto value = interp.specifier(node); + } + + auto declaratorResult = interp.declarator(ast->declarator); + auto newInitalizerResult = interp.newInitializer(ast->newInitalizer); + + return ExpressionResult{std::nullopt}; +} + +auto ASTInterpreter::ExpressionVisitor::operator()(DeleteExpressionAST* ast) + -> ExpressionResult { + auto expressionResult = interp.expression(ast->expression); + + return ExpressionResult{std::nullopt}; +} + +auto ASTInterpreter::ExpressionVisitor::operator()(CastExpressionAST* ast) + -> ExpressionResult { + auto typeIdResult = interp.typeId(ast->typeId); + auto expressionResult = interp.expression(ast->expression); + + return ExpressionResult{std::nullopt}; +} + +auto ASTInterpreter::ExpressionVisitor::operator()( + ImplicitCastExpressionAST* ast) -> ExpressionResult { + if (!ast->type) return std::nullopt; + + auto value = evaluate(ast->expression); + if (!value.has_value()) return std::nullopt; + + switch (ast->type->kind()) { + case TypeKind::kBool: { + auto result = interp.toBool(*value); + if (!result.has_value()) return std::nullopt; + return result.value(); + } + + case TypeKind::kFloat: { + auto result = interp.toFloat(*value); + if (!result.has_value()) return std::nullopt; + return result.value(); + } + + case TypeKind::kDouble: { + auto result = interp.toDouble(*value); + if (!result.has_value()) return std::nullopt; + return result.value(); + } + + case TypeKind::kLongDouble: { + auto result = interp.toLongDouble(*value); + if (!result.has_value()) return std::nullopt; + return result.value(); + } + + default: + if (control()->is_integral_or_unscoped_enum(ast->type)) { + if (control()->is_unsigned(ast->type)) { + auto result = interp.toUInt(*value); + if (!result.has_value()) return std::nullopt; + return ConstValue{std::bit_cast(result.value())}; + } + + auto result = interp.toInt(*value); + if (!result.has_value()) return std::nullopt; + return result.value(); + } + + return value; + } // switch + + return std::nullopt; +} + +auto ASTInterpreter::ExpressionVisitor::operator()(BinaryExpressionAST* ast) + -> ExpressionResult { + if (!ast->type) return std::nullopt; + + auto left = evaluate(ast->leftExpression); + if (!left.has_value()) return std::nullopt; + + auto right = evaluate(ast->rightExpression); + if (!right.has_value()) return std::nullopt; + + switch (ast->op) { + case TokenKind::T_DOT_STAR: + break; + + case TokenKind::T_MINUS_GREATER_STAR: + break; + + case TokenKind::T_STAR: + return star_op(ast, left, right); + + case TokenKind::T_SLASH: + return slash_op(ast, left, right); + + case TokenKind::T_PERCENT: + return percent_op(ast, left, right); + + case TokenKind::T_PLUS: + return plus_op(ast, left, right); + + case TokenKind::T_MINUS: + return minus_op(ast, left, right); + + case TokenKind::T_LESS_LESS: + return less_less_op(ast, left, right); + + case TokenKind::T_GREATER_GREATER: + return greater_greater_op(ast, left, right); + + case TokenKind::T_LESS_EQUAL_GREATER: + return less_equal_greater_op(ast, left, right); + + case TokenKind::T_LESS_EQUAL: + return less_equal_op(ast, left, right); + + case TokenKind::T_GREATER_EQUAL: + return greater_equal_op(ast, left, right); + + case TokenKind::T_LESS: + return less_op(ast, left, right); + + case TokenKind::T_GREATER: + return greater_op(ast, left, right); + + case TokenKind::T_EQUAL_EQUAL: + return equal_equal_op(ast, left, right); + + case TokenKind::T_EXCLAIM_EQUAL: + return exclaim_equal_op(ast, left, right); + + case TokenKind::T_AMP: + return amp_op(ast, left, right); + + case TokenKind::T_CARET: + return caret_op(ast, left, right); + + case TokenKind::T_BAR: + return bar_op(ast, left, right); + + case TokenKind::T_AMP_AMP: + return amp_amp_op(ast, left, right); + + case TokenKind::T_BAR_BAR: + return bar_bar_op(ast, left, right); + + case TokenKind::T_COMMA: + return comma_op(ast, left, right); + + default: + unit()->warning(ast->opLoc, "invalid binary expression"); + break; + } // switch + + return std::nullopt; +} + +auto ASTInterpreter::ExpressionVisitor::operator()( + ConditionalExpressionAST* ast) -> ExpressionResult { + auto conditionResult = interp.expression(ast->condition); + + if (!conditionResult.has_value()) return std::nullopt; + + if (interp.toBool(conditionResult.value())) { + auto result = interp.expression(ast->iftrueExpression); + return result; + } + + auto result = interp.expression(ast->iffalseExpression); + + return result; +} + +auto ASTInterpreter::ExpressionVisitor::operator()(YieldExpressionAST* ast) + -> ExpressionResult { + auto expressionResult = interp.expression(ast->expression); + + return ExpressionResult{std::nullopt}; +} + +auto ASTInterpreter::ExpressionVisitor::operator()(ThrowExpressionAST* ast) + -> ExpressionResult { + auto expressionResult = interp.expression(ast->expression); + + return ExpressionResult{std::nullopt}; +} + +auto ASTInterpreter::ExpressionVisitor::operator()(AssignmentExpressionAST* ast) + -> ExpressionResult { + auto leftExpressionResult = interp.expression(ast->leftExpression); + auto rightExpressionResult = interp.expression(ast->rightExpression); + + return ExpressionResult{std::nullopt}; +} + +auto ASTInterpreter::ExpressionVisitor::operator()( + CompoundAssignmentExpressionAST* ast) -> ExpressionResult { + auto leftExpressionResult = interp.expression(ast->leftExpression); + auto rightExpressionResult = interp.expression(ast->rightExpression); + + return ExpressionResult{std::nullopt}; +} + +auto ASTInterpreter::ExpressionVisitor::operator()( + PackExpansionExpressionAST* ast) -> ExpressionResult { + auto expressionResult = interp.expression(ast->expression); + + return ExpressionResult{std::nullopt}; +} + +auto ASTInterpreter::ExpressionVisitor::operator()( + DesignatedInitializerClauseAST* ast) -> ExpressionResult { + auto initializerResult = interp.expression(ast->initializer); + + return ExpressionResult{std::nullopt}; +} + +auto ASTInterpreter::ExpressionVisitor::operator()(TypeTraitExpressionAST* ast) + -> ExpressionResult { +#if false + for (auto node : ListView{ast->typeIdList}) { + auto value = interp(node); + } +#endif + + const Type* firstType = nullptr; + const Type* secondType = nullptr; + + if (ast->typeIdList && ast->typeIdList->value) { + firstType = ast->typeIdList->value->type; + + if (auto next = ast->typeIdList->next; next && next->value) { + secondType = next->value->type; + } + } + + if (firstType) { + switch (ast->typeTrait) { + case BuiltinTypeTraitKind::T___IS_VOID: + return control()->is_void(firstType); + + case BuiltinTypeTraitKind::T___IS_NULL_POINTER: + return control()->is_null_pointer(firstType); + + case BuiltinTypeTraitKind::T___IS_INTEGRAL: + return control()->is_integral(firstType); + + case BuiltinTypeTraitKind::T___IS_FLOATING_POINT: + return control()->is_floating_point(firstType); + + case BuiltinTypeTraitKind::T___IS_ARRAY: + return control()->is_array(firstType); + + case BuiltinTypeTraitKind::T___IS_ENUM: + return control()->is_enum(firstType); + + case BuiltinTypeTraitKind::T___IS_SCOPED_ENUM: + return control()->is_scoped_enum(firstType); + + case BuiltinTypeTraitKind::T___IS_UNION: + return control()->is_union(firstType); + + case BuiltinTypeTraitKind::T___IS_CLASS: + return control()->is_class(firstType); + + case BuiltinTypeTraitKind::T___IS_FUNCTION: + return control()->is_function(firstType); + + case BuiltinTypeTraitKind::T___IS_POINTER: + return control()->is_pointer(firstType); + + case BuiltinTypeTraitKind::T___IS_MEMBER_OBJECT_POINTER: + return control()->is_member_object_pointer(firstType); + + case BuiltinTypeTraitKind::T___IS_MEMBER_FUNCTION_POINTER: + return control()->is_member_function_pointer(firstType); + + case BuiltinTypeTraitKind::T___IS_LVALUE_REFERENCE: + return control()->is_lvalue_reference(firstType); + + case BuiltinTypeTraitKind::T___IS_RVALUE_REFERENCE: + return control()->is_rvalue_reference(firstType); + + case BuiltinTypeTraitKind::T___IS_FUNDAMENTAL: + return control()->is_fundamental(firstType); + + case BuiltinTypeTraitKind::T___IS_ARITHMETIC: + return control()->is_arithmetic(firstType); + + case BuiltinTypeTraitKind::T___IS_SCALAR: + return control()->is_scalar(firstType); + + case BuiltinTypeTraitKind::T___IS_OBJECT: + return control()->is_object(firstType); + + case BuiltinTypeTraitKind::T___IS_COMPOUND: + return control()->is_compound(firstType); + + case BuiltinTypeTraitKind::T___IS_REFERENCE: + return control()->is_reference(firstType); + + case BuiltinTypeTraitKind::T___IS_MEMBER_POINTER: + return control()->is_member_pointer(firstType); + + case BuiltinTypeTraitKind::T___IS_BOUNDED_ARRAY: + return control()->is_bounded_array(firstType); + + case BuiltinTypeTraitKind::T___IS_UNBOUNDED_ARRAY: + return control()->is_unbounded_array(firstType); + + case BuiltinTypeTraitKind::T___IS_CONST: + return control()->is_const(firstType); + + case BuiltinTypeTraitKind::T___IS_VOLATILE: + return control()->is_volatile(firstType); + + case BuiltinTypeTraitKind::T___IS_SIGNED: + return control()->is_signed(firstType); + + case BuiltinTypeTraitKind::T___IS_UNSIGNED: + return control()->is_unsigned(firstType); + + case BuiltinTypeTraitKind::T___IS_SAME: + case BuiltinTypeTraitKind::T___IS_SAME_AS: { + if (!secondType) break; + return control()->is_same(firstType, secondType); + } + + case BuiltinTypeTraitKind::T___IS_BASE_OF: { + if (!secondType) break; + return control()->is_base_of(firstType, secondType); + } + + case BuiltinTypeTraitKind::T___HAS_UNIQUE_OBJECT_REPRESENTATIONS: { + break; + } + + case BuiltinTypeTraitKind::T___HAS_VIRTUAL_DESTRUCTOR: { + break; + } + + case BuiltinTypeTraitKind::T___IS_ABSTRACT: { + break; + } + + case BuiltinTypeTraitKind::T___IS_AGGREGATE: { + break; + } + + case BuiltinTypeTraitKind::T___IS_ASSIGNABLE: { + break; + } + + case BuiltinTypeTraitKind::T___IS_EMPTY: { + break; + } + + case BuiltinTypeTraitKind::T___IS_FINAL: { + if (auto classType = + type_cast(control()->remove_cv(firstType))) { + return classType->symbol()->isFinal(); + } + break; + } + + case BuiltinTypeTraitKind::T___IS_LAYOUT_COMPATIBLE: { + break; + } + + case BuiltinTypeTraitKind::T___IS_LITERAL_TYPE: { + break; + } + + case BuiltinTypeTraitKind::T___IS_POD: { + break; + } + + case BuiltinTypeTraitKind::T___IS_POLYMORPHIC: { + break; + } + + case BuiltinTypeTraitKind::T___IS_STANDARD_LAYOUT: { + break; + } + + case BuiltinTypeTraitKind::T___IS_SWAPPABLE_WITH: { + break; + } + + case BuiltinTypeTraitKind::T___IS_TRIVIAL: { + break; + } + + case BuiltinTypeTraitKind::T___IS_TRIVIALLY_CONSTRUCTIBLE: { + break; + } + + case BuiltinTypeTraitKind::T___IS_TRIVIALLY_ASSIGNABLE: { + break; + } + + case BuiltinTypeTraitKind::T_NONE: { + // not a builtin + break; + } + + } // switch + } + + return std::nullopt; +} + +auto ASTInterpreter::ExpressionVisitor::operator()(ConditionExpressionAST* ast) + -> ExpressionResult { + for (auto node : ListView{ast->attributeList}) { + auto value = interp.attributeSpecifier(node); + } + + for (auto node : ListView{ast->declSpecifierList}) { + auto value = interp.specifier(node); + } + + auto declaratorResult = interp.declarator(ast->declarator); + auto initializerResult = interp.expression(ast->initializer); + + return ExpressionResult{std::nullopt}; +} + +auto ASTInterpreter::ExpressionVisitor::operator()(EqualInitializerAST* ast) + -> ExpressionResult { + auto expressionResult = interp.expression(ast->expression); + + return expressionResult; +} + +auto ASTInterpreter::ExpressionVisitor::operator()(BracedInitListAST* ast) + -> ExpressionResult { + for (auto node : ListView{ast->expressionList}) { + auto value = interp.expression(node); + } + + return ExpressionResult{std::nullopt}; +} + +auto ASTInterpreter::ExpressionVisitor::operator()(ParenInitializerAST* ast) + -> ExpressionResult { + for (auto node : ListView{ast->expressionList}) { + auto value = interp.expression(node); + } + + return ExpressionResult{std::nullopt}; +} + +auto ASTInterpreter::NewInitializerVisitor::operator()( + NewParenInitializerAST* ast) -> NewInitializerResult { + for (auto node : ListView{ast->expressionList}) { + auto value = interp.expression(node); + } + + return {}; +} + +auto ASTInterpreter::NewInitializerVisitor::operator()( + NewBracedInitializerAST* ast) -> NewInitializerResult { + auto bracedInitListResult = interp.expression(ast->bracedInitList); + + return {}; +} + +} // namespace cxx diff --git a/src/parser/cxx/ast_interpreter_names.cc b/src/parser/cxx/ast_interpreter_names.cc new file mode 100644 index 00000000..f579b50a --- /dev/null +++ b/src/parser/cxx/ast_interpreter_names.cc @@ -0,0 +1,219 @@ +// Copyright (c) 2025 Roberto Raggi +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. + +#include + +// cxx +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +namespace cxx { + +struct ASTInterpreter::UnqualifiedIdVisitor { + ASTInterpreter& interp; + + [[nodiscard]] auto operator()(NameIdAST* ast) -> UnqualifiedIdResult; + + [[nodiscard]] auto operator()(DestructorIdAST* ast) -> UnqualifiedIdResult; + + [[nodiscard]] auto operator()(DecltypeIdAST* ast) -> UnqualifiedIdResult; + + [[nodiscard]] auto operator()(OperatorFunctionIdAST* ast) + -> UnqualifiedIdResult; + + [[nodiscard]] auto operator()(LiteralOperatorIdAST* ast) + -> UnqualifiedIdResult; + + [[nodiscard]] auto operator()(ConversionFunctionIdAST* ast) + -> UnqualifiedIdResult; + + [[nodiscard]] auto operator()(SimpleTemplateIdAST* ast) + -> UnqualifiedIdResult; + + [[nodiscard]] auto operator()(LiteralOperatorTemplateIdAST* ast) + -> UnqualifiedIdResult; + + [[nodiscard]] auto operator()(OperatorFunctionTemplateIdAST* ast) + -> UnqualifiedIdResult; +}; + +struct ASTInterpreter::NestedNameSpecifierVisitor { + ASTInterpreter& interp; + + [[nodiscard]] auto operator()(GlobalNestedNameSpecifierAST* ast) + -> NestedNameSpecifierResult; + + [[nodiscard]] auto operator()(SimpleNestedNameSpecifierAST* ast) + -> NestedNameSpecifierResult; + + [[nodiscard]] auto operator()(DecltypeNestedNameSpecifierAST* ast) + -> NestedNameSpecifierResult; + + [[nodiscard]] auto operator()(TemplateNestedNameSpecifierAST* ast) + -> NestedNameSpecifierResult; +}; + +struct ASTInterpreter::TemplateArgumentVisitor { + ASTInterpreter& interp; + + [[nodiscard]] auto operator()(TypeTemplateArgumentAST* ast) + -> TemplateArgumentResult; + + [[nodiscard]] auto operator()(ExpressionTemplateArgumentAST* ast) + -> TemplateArgumentResult; +}; + +auto ASTInterpreter::unqualifiedId(UnqualifiedIdAST* ast) + -> UnqualifiedIdResult { + if (ast) return visit(UnqualifiedIdVisitor{*this}, ast); + return {}; +} + +auto ASTInterpreter::nestedNameSpecifier(NestedNameSpecifierAST* ast) + -> NestedNameSpecifierResult { + if (ast) return visit(NestedNameSpecifierVisitor{*this}, ast); + return {}; +} + +auto ASTInterpreter::templateArgument(TemplateArgumentAST* ast) + -> TemplateArgumentResult { + if (ast) return visit(TemplateArgumentVisitor{*this}, ast); + return {}; +} + +auto ASTInterpreter::UnqualifiedIdVisitor::operator()(NameIdAST* ast) + -> UnqualifiedIdResult { + return {}; +} + +auto ASTInterpreter::UnqualifiedIdVisitor::operator()(DestructorIdAST* ast) + -> UnqualifiedIdResult { + auto idResult = interp.unqualifiedId(ast->id); + + return {}; +} + +auto ASTInterpreter::UnqualifiedIdVisitor::operator()(DecltypeIdAST* ast) + -> UnqualifiedIdResult { + auto decltypeSpecifierResult = interp.specifier(ast->decltypeSpecifier); + + return {}; +} + +auto ASTInterpreter::UnqualifiedIdVisitor::operator()( + OperatorFunctionIdAST* ast) -> UnqualifiedIdResult { + return {}; +} + +auto ASTInterpreter::UnqualifiedIdVisitor::operator()(LiteralOperatorIdAST* ast) + -> UnqualifiedIdResult { + return {}; +} + +auto ASTInterpreter::UnqualifiedIdVisitor::operator()( + ConversionFunctionIdAST* ast) -> UnqualifiedIdResult { + auto typeIdResult = interp.typeId(ast->typeId); + + return {}; +} + +auto ASTInterpreter::UnqualifiedIdVisitor::operator()(SimpleTemplateIdAST* ast) + -> UnqualifiedIdResult { + for (auto node : ListView{ast->templateArgumentList}) { + auto value = interp.templateArgument(node); + } + + return {}; +} + +auto ASTInterpreter::UnqualifiedIdVisitor::operator()( + LiteralOperatorTemplateIdAST* ast) -> UnqualifiedIdResult { + auto literalOperatorIdResult = interp.unqualifiedId(ast->literalOperatorId); + + for (auto node : ListView{ast->templateArgumentList}) { + auto value = interp.templateArgument(node); + } + + return {}; +} + +auto ASTInterpreter::UnqualifiedIdVisitor::operator()( + OperatorFunctionTemplateIdAST* ast) -> UnqualifiedIdResult { + auto operatorFunctionIdResult = interp.unqualifiedId(ast->operatorFunctionId); + + for (auto node : ListView{ast->templateArgumentList}) { + auto value = interp.templateArgument(node); + } + + return {}; +} + +auto ASTInterpreter::NestedNameSpecifierVisitor::operator()( + GlobalNestedNameSpecifierAST* ast) -> NestedNameSpecifierResult { + return {}; +} + +auto ASTInterpreter::NestedNameSpecifierVisitor::operator()( + SimpleNestedNameSpecifierAST* ast) -> NestedNameSpecifierResult { + auto nestedNameSpecifierResult = + interp.nestedNameSpecifier(ast->nestedNameSpecifier); + + return {}; +} + +auto ASTInterpreter::NestedNameSpecifierVisitor::operator()( + DecltypeNestedNameSpecifierAST* ast) -> NestedNameSpecifierResult { + auto decltypeSpecifierResult = interp.specifier(ast->decltypeSpecifier); + + return {}; +} + +auto ASTInterpreter::NestedNameSpecifierVisitor::operator()( + TemplateNestedNameSpecifierAST* ast) -> NestedNameSpecifierResult { + auto nestedNameSpecifierResult = + interp.nestedNameSpecifier(ast->nestedNameSpecifier); + auto templateIdResult = interp.unqualifiedId(ast->templateId); + + return {}; +} + +auto ASTInterpreter::TemplateArgumentVisitor::operator()( + TypeTemplateArgumentAST* ast) -> TemplateArgumentResult { + auto typeIdResult = interp.typeId(ast->typeId); + + return {}; +} + +auto ASTInterpreter::TemplateArgumentVisitor::operator()( + ExpressionTemplateArgumentAST* ast) -> TemplateArgumentResult { + auto expressionResult = interp.expression(ast->expression); + + return {}; +} + +} // namespace cxx diff --git a/src/parser/cxx/ast_interpreter_specifiers.cc b/src/parser/cxx/ast_interpreter_specifiers.cc new file mode 100644 index 00000000..93a51f00 --- /dev/null +++ b/src/parser/cxx/ast_interpreter_specifiers.cc @@ -0,0 +1,557 @@ +// Copyright (c) 2025 Roberto Raggi +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. + +#include + +// cxx +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +namespace cxx { + +struct ASTInterpreter::SpecifierVisitor { + ASTInterpreter& interp; + + [[nodiscard]] auto operator()(TypedefSpecifierAST* ast) -> SpecifierResult; + + [[nodiscard]] auto operator()(FriendSpecifierAST* ast) -> SpecifierResult; + + [[nodiscard]] auto operator()(ConstevalSpecifierAST* ast) -> SpecifierResult; + + [[nodiscard]] auto operator()(ConstinitSpecifierAST* ast) -> SpecifierResult; + + [[nodiscard]] auto operator()(ConstexprSpecifierAST* ast) -> SpecifierResult; + + [[nodiscard]] auto operator()(InlineSpecifierAST* ast) -> SpecifierResult; + + [[nodiscard]] auto operator()(NoreturnSpecifierAST* ast) -> SpecifierResult; + + [[nodiscard]] auto operator()(StaticSpecifierAST* ast) -> SpecifierResult; + + [[nodiscard]] auto operator()(ExternSpecifierAST* ast) -> SpecifierResult; + + [[nodiscard]] auto operator()(RegisterSpecifierAST* ast) -> SpecifierResult; + + [[nodiscard]] auto operator()(ThreadLocalSpecifierAST* ast) + -> SpecifierResult; + + [[nodiscard]] auto operator()(ThreadSpecifierAST* ast) -> SpecifierResult; + + [[nodiscard]] auto operator()(MutableSpecifierAST* ast) -> SpecifierResult; + + [[nodiscard]] auto operator()(VirtualSpecifierAST* ast) -> SpecifierResult; + + [[nodiscard]] auto operator()(ExplicitSpecifierAST* ast) -> SpecifierResult; + + [[nodiscard]] auto operator()(AutoTypeSpecifierAST* ast) -> SpecifierResult; + + [[nodiscard]] auto operator()(VoidTypeSpecifierAST* ast) -> SpecifierResult; + + [[nodiscard]] auto operator()(SizeTypeSpecifierAST* ast) -> SpecifierResult; + + [[nodiscard]] auto operator()(SignTypeSpecifierAST* ast) -> SpecifierResult; + + [[nodiscard]] auto operator()(BuiltinTypeSpecifierAST* ast) + -> SpecifierResult; + + [[nodiscard]] auto operator()(UnaryBuiltinTypeSpecifierAST* ast) + -> SpecifierResult; + + [[nodiscard]] auto operator()(BinaryBuiltinTypeSpecifierAST* ast) + -> SpecifierResult; + + [[nodiscard]] auto operator()(IntegralTypeSpecifierAST* ast) + -> SpecifierResult; + + [[nodiscard]] auto operator()(FloatingPointTypeSpecifierAST* ast) + -> SpecifierResult; + + [[nodiscard]] auto operator()(ComplexTypeSpecifierAST* ast) + -> SpecifierResult; + + [[nodiscard]] auto operator()(NamedTypeSpecifierAST* ast) -> SpecifierResult; + + [[nodiscard]] auto operator()(AtomicTypeSpecifierAST* ast) -> SpecifierResult; + + [[nodiscard]] auto operator()(UnderlyingTypeSpecifierAST* ast) + -> SpecifierResult; + + [[nodiscard]] auto operator()(ElaboratedTypeSpecifierAST* ast) + -> SpecifierResult; + + [[nodiscard]] auto operator()(DecltypeAutoSpecifierAST* ast) + -> SpecifierResult; + + [[nodiscard]] auto operator()(DecltypeSpecifierAST* ast) -> SpecifierResult; + + [[nodiscard]] auto operator()(PlaceholderTypeSpecifierAST* ast) + -> SpecifierResult; + + [[nodiscard]] auto operator()(ConstQualifierAST* ast) -> SpecifierResult; + + [[nodiscard]] auto operator()(VolatileQualifierAST* ast) -> SpecifierResult; + + [[nodiscard]] auto operator()(RestrictQualifierAST* ast) -> SpecifierResult; + + [[nodiscard]] auto operator()(AtomicQualifierAST* ast) -> SpecifierResult; + + [[nodiscard]] auto operator()(EnumSpecifierAST* ast) -> SpecifierResult; + + [[nodiscard]] auto operator()(ClassSpecifierAST* ast) -> SpecifierResult; + + [[nodiscard]] auto operator()(TypenameSpecifierAST* ast) -> SpecifierResult; + + [[nodiscard]] auto operator()(SplicerTypeSpecifierAST* ast) + -> SpecifierResult; +}; + +struct ASTInterpreter::AttributeSpecifierVisitor { + ASTInterpreter& interp; + + [[nodiscard]] auto operator()(CxxAttributeAST* ast) + -> AttributeSpecifierResult; + + [[nodiscard]] auto operator()(GccAttributeAST* ast) + -> AttributeSpecifierResult; + + [[nodiscard]] auto operator()(AlignasAttributeAST* ast) + -> AttributeSpecifierResult; + + [[nodiscard]] auto operator()(AlignasTypeAttributeAST* ast) + -> AttributeSpecifierResult; + + [[nodiscard]] auto operator()(AsmAttributeAST* ast) + -> AttributeSpecifierResult; +}; + +struct ASTInterpreter::AttributeTokenVisitor { + ASTInterpreter& interp; + + [[nodiscard]] auto operator()(ScopedAttributeTokenAST* ast) + -> AttributeTokenResult; + + [[nodiscard]] auto operator()(SimpleAttributeTokenAST* ast) + -> AttributeTokenResult; +}; + +auto ASTInterpreter::specifier(SpecifierAST* ast) -> SpecifierResult { + if (ast) return visit(SpecifierVisitor{*this}, ast); + return {}; +} + +auto ASTInterpreter::attributeSpecifier(AttributeSpecifierAST* ast) + -> AttributeSpecifierResult { + if (ast) return visit(AttributeSpecifierVisitor{*this}, ast); + return {}; +} + +auto ASTInterpreter::attributeToken(AttributeTokenAST* ast) + -> AttributeTokenResult { + if (ast) return visit(AttributeTokenVisitor{*this}, ast); + return {}; +} + +auto ASTInterpreter::baseSpecifier(BaseSpecifierAST* ast) + -> BaseSpecifierResult { + if (!ast) return {}; + + for (auto node : ListView{ast->attributeList}) { + auto value = attributeSpecifier(node); + } + + auto nestedNameSpecifierResult = + nestedNameSpecifier(ast->nestedNameSpecifier); + auto unqualifiedIdResult = unqualifiedId(ast->unqualifiedId); + + return {}; +} + +auto ASTInterpreter::enumerator(EnumeratorAST* ast) -> EnumeratorResult { + if (!ast) return {}; + + for (auto node : ListView{ast->attributeList}) { + auto value = attributeSpecifier(node); + } + + auto expressionResult = expression(ast->expression); + + return {}; +} + +auto ASTInterpreter::typeId(TypeIdAST* ast) -> TypeIdResult { + if (!ast) return {}; + + for (auto node : ListView{ast->typeSpecifierList}) { + auto value = specifier(node); + } + + auto declaratorResult = declarator(ast->declarator); + + return {}; +} + +auto ASTInterpreter::attributeArgumentClause(AttributeArgumentClauseAST* ast) + -> AttributeArgumentClauseResult { + if (!ast) return {}; + + return {}; +} + +auto ASTInterpreter::attribute(AttributeAST* ast) -> AttributeResult { + if (!ast) return {}; + + auto attributeTokenResult = attributeToken(ast->attributeToken); + auto attributeArgumentClauseResult = + attributeArgumentClause(ast->attributeArgumentClause); + + return {}; +} + +auto ASTInterpreter::attributeUsingPrefix(AttributeUsingPrefixAST* ast) + -> AttributeUsingPrefixResult { + if (!ast) return {}; + + return {}; +} + +auto ASTInterpreter::splicer(SplicerAST* ast) -> ExpressionResult { + if (!ast) return {}; + + auto expressionResult = expression(ast->expression); + + return expressionResult; +} + +auto ASTInterpreter::SpecifierVisitor::operator()(TypedefSpecifierAST* ast) + -> SpecifierResult { + return {}; +} + +auto ASTInterpreter::SpecifierVisitor::operator()(FriendSpecifierAST* ast) + -> SpecifierResult { + return {}; +} + +auto ASTInterpreter::SpecifierVisitor::operator()(ConstevalSpecifierAST* ast) + -> SpecifierResult { + return {}; +} + +auto ASTInterpreter::SpecifierVisitor::operator()(ConstinitSpecifierAST* ast) + -> SpecifierResult { + return {}; +} + +auto ASTInterpreter::SpecifierVisitor::operator()(ConstexprSpecifierAST* ast) + -> SpecifierResult { + return {}; +} + +auto ASTInterpreter::SpecifierVisitor::operator()(InlineSpecifierAST* ast) + -> SpecifierResult { + return {}; +} + +auto ASTInterpreter::SpecifierVisitor::operator()(NoreturnSpecifierAST* ast) + -> SpecifierResult { + return {}; +} + +auto ASTInterpreter::SpecifierVisitor::operator()(StaticSpecifierAST* ast) + -> SpecifierResult { + return {}; +} + +auto ASTInterpreter::SpecifierVisitor::operator()(ExternSpecifierAST* ast) + -> SpecifierResult { + return {}; +} + +auto ASTInterpreter::SpecifierVisitor::operator()(RegisterSpecifierAST* ast) + -> SpecifierResult { + return {}; +} + +auto ASTInterpreter::SpecifierVisitor::operator()(ThreadLocalSpecifierAST* ast) + -> SpecifierResult { + return {}; +} + +auto ASTInterpreter::SpecifierVisitor::operator()(ThreadSpecifierAST* ast) + -> SpecifierResult { + return {}; +} + +auto ASTInterpreter::SpecifierVisitor::operator()(MutableSpecifierAST* ast) + -> SpecifierResult { + return {}; +} + +auto ASTInterpreter::SpecifierVisitor::operator()(VirtualSpecifierAST* ast) + -> SpecifierResult { + return {}; +} + +auto ASTInterpreter::SpecifierVisitor::operator()(ExplicitSpecifierAST* ast) + -> SpecifierResult { + auto expressionResult = interp.expression(ast->expression); + + return {}; +} + +auto ASTInterpreter::SpecifierVisitor::operator()(AutoTypeSpecifierAST* ast) + -> SpecifierResult { + return {}; +} + +auto ASTInterpreter::SpecifierVisitor::operator()(VoidTypeSpecifierAST* ast) + -> SpecifierResult { + return {}; +} + +auto ASTInterpreter::SpecifierVisitor::operator()(SizeTypeSpecifierAST* ast) + -> SpecifierResult { + return {}; +} + +auto ASTInterpreter::SpecifierVisitor::operator()(SignTypeSpecifierAST* ast) + -> SpecifierResult { + return {}; +} + +auto ASTInterpreter::SpecifierVisitor::operator()(BuiltinTypeSpecifierAST* ast) + -> SpecifierResult { + return {}; +} + +auto ASTInterpreter::SpecifierVisitor::operator()( + UnaryBuiltinTypeSpecifierAST* ast) -> SpecifierResult { + return {}; +} + +auto ASTInterpreter::SpecifierVisitor::operator()( + BinaryBuiltinTypeSpecifierAST* ast) -> SpecifierResult { + return {}; +} + +auto ASTInterpreter::SpecifierVisitor::operator()(IntegralTypeSpecifierAST* ast) + -> SpecifierResult { + return {}; +} + +auto ASTInterpreter::SpecifierVisitor::operator()( + FloatingPointTypeSpecifierAST* ast) -> SpecifierResult { + return {}; +} + +auto ASTInterpreter::SpecifierVisitor::operator()(ComplexTypeSpecifierAST* ast) + -> SpecifierResult { + return {}; +} + +auto ASTInterpreter::SpecifierVisitor::operator()(NamedTypeSpecifierAST* ast) + -> SpecifierResult { + auto nestedNameSpecifierResult = + interp.nestedNameSpecifier(ast->nestedNameSpecifier); + auto unqualifiedIdResult = interp.unqualifiedId(ast->unqualifiedId); + + return {}; +} + +auto ASTInterpreter::SpecifierVisitor::operator()(AtomicTypeSpecifierAST* ast) + -> SpecifierResult { + auto typeIdResult = interp.typeId(ast->typeId); + + return {}; +} + +auto ASTInterpreter::SpecifierVisitor::operator()( + UnderlyingTypeSpecifierAST* ast) -> SpecifierResult { + auto typeIdResult = interp.typeId(ast->typeId); + + return {}; +} + +auto ASTInterpreter::SpecifierVisitor::operator()( + ElaboratedTypeSpecifierAST* ast) -> SpecifierResult { + for (auto node : ListView{ast->attributeList}) { + auto value = interp.attributeSpecifier(node); + } + + auto nestedNameSpecifierResult = + interp.nestedNameSpecifier(ast->nestedNameSpecifier); + auto unqualifiedIdResult = interp.unqualifiedId(ast->unqualifiedId); + + return {}; +} + +auto ASTInterpreter::SpecifierVisitor::operator()(DecltypeAutoSpecifierAST* ast) + -> SpecifierResult { + return {}; +} + +auto ASTInterpreter::SpecifierVisitor::operator()(DecltypeSpecifierAST* ast) + -> SpecifierResult { + auto expressionResult = interp.expression(ast->expression); + + return {}; +} + +auto ASTInterpreter::SpecifierVisitor::operator()( + PlaceholderTypeSpecifierAST* ast) -> SpecifierResult { + auto typeConstraintResult = interp.typeConstraint(ast->typeConstraint); + auto specifierResult = interp.specifier(ast->specifier); + + return {}; +} + +auto ASTInterpreter::SpecifierVisitor::operator()(ConstQualifierAST* ast) + -> SpecifierResult { + return {}; +} + +auto ASTInterpreter::SpecifierVisitor::operator()(VolatileQualifierAST* ast) + -> SpecifierResult { + return {}; +} + +auto ASTInterpreter::SpecifierVisitor::operator()(RestrictQualifierAST* ast) + -> SpecifierResult { + return {}; +} + +auto ASTInterpreter::SpecifierVisitor::operator()(AtomicQualifierAST* ast) + -> SpecifierResult { + return {}; +} + +auto ASTInterpreter::SpecifierVisitor::operator()(EnumSpecifierAST* ast) + -> SpecifierResult { + for (auto node : ListView{ast->attributeList}) { + auto value = interp.attributeSpecifier(node); + } + + auto nestedNameSpecifierResult = + interp.nestedNameSpecifier(ast->nestedNameSpecifier); + auto unqualifiedIdResult = interp.unqualifiedId(ast->unqualifiedId); + + for (auto node : ListView{ast->typeSpecifierList}) { + auto value = interp.specifier(node); + } + + for (auto node : ListView{ast->enumeratorList}) { + auto value = interp.enumerator(node); + } + + return {}; +} + +auto ASTInterpreter::SpecifierVisitor::operator()(ClassSpecifierAST* ast) + -> SpecifierResult { + for (auto node : ListView{ast->attributeList}) { + auto value = interp.attributeSpecifier(node); + } + + auto nestedNameSpecifierResult = + interp.nestedNameSpecifier(ast->nestedNameSpecifier); + auto unqualifiedIdResult = interp.unqualifiedId(ast->unqualifiedId); + + for (auto node : ListView{ast->baseSpecifierList}) { + auto value = interp.baseSpecifier(node); + } + + for (auto node : ListView{ast->declarationList}) { + auto value = interp.declaration(node); + } + + return {}; +} + +auto ASTInterpreter::SpecifierVisitor::operator()(TypenameSpecifierAST* ast) + -> SpecifierResult { + auto nestedNameSpecifierResult = + interp.nestedNameSpecifier(ast->nestedNameSpecifier); + auto unqualifiedIdResult = interp.unqualifiedId(ast->unqualifiedId); + + return {}; +} + +auto ASTInterpreter::SpecifierVisitor::operator()(SplicerTypeSpecifierAST* ast) + -> SpecifierResult { + auto splicerResult = interp.splicer(ast->splicer); + + return {}; +} + +auto ASTInterpreter::AttributeSpecifierVisitor::operator()(CxxAttributeAST* ast) + -> AttributeSpecifierResult { + auto attributeUsingPrefixResult = + interp.attributeUsingPrefix(ast->attributeUsingPrefix); + + for (auto node : ListView{ast->attributeList}) { + auto value = interp.attribute(node); + } + + return {}; +} + +auto ASTInterpreter::AttributeSpecifierVisitor::operator()(GccAttributeAST* ast) + -> AttributeSpecifierResult { + return {}; +} + +auto ASTInterpreter::AttributeSpecifierVisitor::operator()( + AlignasAttributeAST* ast) -> AttributeSpecifierResult { + auto expressionResult = interp.expression(ast->expression); + + return {}; +} + +auto ASTInterpreter::AttributeSpecifierVisitor::operator()( + AlignasTypeAttributeAST* ast) -> AttributeSpecifierResult { + auto typeIdResult = interp.typeId(ast->typeId); + + return {}; +} + +auto ASTInterpreter::AttributeSpecifierVisitor::operator()(AsmAttributeAST* ast) + -> AttributeSpecifierResult { + return {}; +} + +auto ASTInterpreter::AttributeTokenVisitor::operator()( + ScopedAttributeTokenAST* ast) -> AttributeTokenResult { + return {}; +} + +auto ASTInterpreter::AttributeTokenVisitor::operator()( + SimpleAttributeTokenAST* ast) -> AttributeTokenResult { + return {}; +} + +} // namespace cxx diff --git a/src/parser/cxx/ast_interpreter_statements.cc b/src/parser/cxx/ast_interpreter_statements.cc new file mode 100644 index 00000000..ac7e7214 --- /dev/null +++ b/src/parser/cxx/ast_interpreter_statements.cc @@ -0,0 +1,276 @@ +// Copyright (c) 2025 Roberto Raggi +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. + +#include + +// cxx +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +namespace cxx { + +struct ASTInterpreter::StatementVisitor { + ASTInterpreter& interp; + + [[nodiscard]] auto operator()(LabeledStatementAST* ast) -> StatementResult; + + [[nodiscard]] auto operator()(CaseStatementAST* ast) -> StatementResult; + + [[nodiscard]] auto operator()(DefaultStatementAST* ast) -> StatementResult; + + [[nodiscard]] auto operator()(ExpressionStatementAST* ast) -> StatementResult; + + [[nodiscard]] auto operator()(CompoundStatementAST* ast) -> StatementResult; + + [[nodiscard]] auto operator()(IfStatementAST* ast) -> StatementResult; + + [[nodiscard]] auto operator()(ConstevalIfStatementAST* ast) + -> StatementResult; + + [[nodiscard]] auto operator()(SwitchStatementAST* ast) -> StatementResult; + + [[nodiscard]] auto operator()(WhileStatementAST* ast) -> StatementResult; + + [[nodiscard]] auto operator()(DoStatementAST* ast) -> StatementResult; + + [[nodiscard]] auto operator()(ForRangeStatementAST* ast) -> StatementResult; + + [[nodiscard]] auto operator()(ForStatementAST* ast) -> StatementResult; + + [[nodiscard]] auto operator()(BreakStatementAST* ast) -> StatementResult; + + [[nodiscard]] auto operator()(ContinueStatementAST* ast) -> StatementResult; + + [[nodiscard]] auto operator()(ReturnStatementAST* ast) -> StatementResult; + + [[nodiscard]] auto operator()(CoroutineReturnStatementAST* ast) + -> StatementResult; + + [[nodiscard]] auto operator()(GotoStatementAST* ast) -> StatementResult; + + [[nodiscard]] auto operator()(DeclarationStatementAST* ast) + -> StatementResult; + + [[nodiscard]] auto operator()(TryBlockStatementAST* ast) -> StatementResult; +}; + +struct ASTInterpreter::ExceptionDeclarationVisitor { + ASTInterpreter& interp; + + [[nodiscard]] auto operator()(EllipsisExceptionDeclarationAST* ast) + -> ExceptionDeclarationResult; + + [[nodiscard]] auto operator()(TypeExceptionDeclarationAST* ast) + -> ExceptionDeclarationResult; +}; + +auto ASTInterpreter::statement(StatementAST* ast) -> StatementResult { + if (ast) return visit(StatementVisitor{*this}, ast); + return {}; +} + +auto ASTInterpreter::handler(HandlerAST* ast) -> HandlerResult { + if (!ast) return {}; + + auto exceptionDeclarationResult = + exceptionDeclaration(ast->exceptionDeclaration); + auto statementResult = statement(ast->statement); + + return {}; +} + +auto ASTInterpreter::exceptionDeclaration(ExceptionDeclarationAST* ast) + -> ExceptionDeclarationResult { + if (ast) return visit(ExceptionDeclarationVisitor{*this}, ast); + return {}; +} + +auto ASTInterpreter::StatementVisitor::operator()(LabeledStatementAST* ast) + -> StatementResult { + return {}; +} + +auto ASTInterpreter::StatementVisitor::operator()(CaseStatementAST* ast) + -> StatementResult { + auto expressionResult = interp.expression(ast->expression); + + return {}; +} + +auto ASTInterpreter::StatementVisitor::operator()(DefaultStatementAST* ast) + -> StatementResult { + return {}; +} + +auto ASTInterpreter::StatementVisitor::operator()(ExpressionStatementAST* ast) + -> StatementResult { + auto expressionResult = interp.expression(ast->expression); + + return {}; +} + +auto ASTInterpreter::StatementVisitor::operator()(CompoundStatementAST* ast) + -> StatementResult { + for (auto node : ListView{ast->statementList}) { + auto value = interp.statement(node); + } + + return {}; +} + +auto ASTInterpreter::StatementVisitor::operator()(IfStatementAST* ast) + -> StatementResult { + auto initializerResult = interp.statement(ast->initializer); + auto conditionResult = interp.expression(ast->condition); + auto statementResult = interp.statement(ast->statement); + auto elseStatementResult = interp.statement(ast->elseStatement); + + return {}; +} + +auto ASTInterpreter::StatementVisitor::operator()(ConstevalIfStatementAST* ast) + -> StatementResult { + auto statementResult = interp.statement(ast->statement); + auto elseStatementResult = interp.statement(ast->elseStatement); + + return {}; +} + +auto ASTInterpreter::StatementVisitor::operator()(SwitchStatementAST* ast) + -> StatementResult { + auto initializerResult = interp.statement(ast->initializer); + auto conditionResult = interp.expression(ast->condition); + auto statementResult = interp.statement(ast->statement); + + return {}; +} + +auto ASTInterpreter::StatementVisitor::operator()(WhileStatementAST* ast) + -> StatementResult { + auto conditionResult = interp.expression(ast->condition); + auto statementResult = interp.statement(ast->statement); + + return {}; +} + +auto ASTInterpreter::StatementVisitor::operator()(DoStatementAST* ast) + -> StatementResult { + auto statementResult = interp.statement(ast->statement); + auto expressionResult = interp.expression(ast->expression); + + return {}; +} + +auto ASTInterpreter::StatementVisitor::operator()(ForRangeStatementAST* ast) + -> StatementResult { + auto initializerResult = interp.statement(ast->initializer); + auto rangeDeclarationResult = interp.declaration(ast->rangeDeclaration); + auto rangeInitializerResult = interp.expression(ast->rangeInitializer); + auto statementResult = interp.statement(ast->statement); + + return {}; +} + +auto ASTInterpreter::StatementVisitor::operator()(ForStatementAST* ast) + -> StatementResult { + auto initializerResult = interp.statement(ast->initializer); + auto conditionResult = interp.expression(ast->condition); + auto expressionResult = interp.expression(ast->expression); + auto statementResult = interp.statement(ast->statement); + + return {}; +} + +auto ASTInterpreter::StatementVisitor::operator()(BreakStatementAST* ast) + -> StatementResult { + return {}; +} + +auto ASTInterpreter::StatementVisitor::operator()(ContinueStatementAST* ast) + -> StatementResult { + return {}; +} + +auto ASTInterpreter::StatementVisitor::operator()(ReturnStatementAST* ast) + -> StatementResult { + auto expressionResult = interp.expression(ast->expression); + + return {}; +} + +auto ASTInterpreter::StatementVisitor::operator()( + CoroutineReturnStatementAST* ast) -> StatementResult { + auto expressionResult = interp.expression(ast->expression); + + return {}; +} + +auto ASTInterpreter::StatementVisitor::operator()(GotoStatementAST* ast) + -> StatementResult { + return {}; +} + +auto ASTInterpreter::StatementVisitor::operator()(DeclarationStatementAST* ast) + -> StatementResult { + auto declarationResult = interp.declaration(ast->declaration); + + return {}; +} + +auto ASTInterpreter::StatementVisitor::operator()(TryBlockStatementAST* ast) + -> StatementResult { + auto statementResult = interp.statement(ast->statement); + + for (auto node : ListView{ast->handlerList}) { + auto value = interp.handler(node); + } + + return {}; +} + +auto ASTInterpreter::ExceptionDeclarationVisitor::operator()( + EllipsisExceptionDeclarationAST* ast) -> ExceptionDeclarationResult { + return {}; +} + +auto ASTInterpreter::ExceptionDeclarationVisitor::operator()( + TypeExceptionDeclarationAST* ast) -> ExceptionDeclarationResult { + for (auto node : ListView{ast->attributeList}) { + auto value = interp.attributeSpecifier(node); + } + + for (auto node : ListView{ast->typeSpecifierList}) { + auto value = interp.specifier(node); + } + + auto declaratorResult = interp.declarator(ast->declarator); + + return {}; +} + +} // namespace cxx diff --git a/src/parser/cxx/ast_interpreter_units.cc b/src/parser/cxx/ast_interpreter_units.cc new file mode 100644 index 00000000..e4824bb4 --- /dev/null +++ b/src/parser/cxx/ast_interpreter_units.cc @@ -0,0 +1,146 @@ +// Copyright (c) 2025 Roberto Raggi +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. + +#include + +// cxx +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +namespace cxx { + +struct ASTInterpreter::UnitVisitor { + ASTInterpreter& interp; + + [[nodiscard]] auto operator()(TranslationUnitAST* ast) -> UnitResult; + + [[nodiscard]] auto operator()(ModuleUnitAST* ast) -> UnitResult; +}; + +auto ASTInterpreter::unit(UnitAST* ast) -> UnitResult { + if (ast) return visit(UnitVisitor{*this}, ast); + return {}; +} + +auto ASTInterpreter::globalModuleFragment(GlobalModuleFragmentAST* ast) + -> GlobalModuleFragmentResult { + if (!ast) return {}; + + for (auto node : ListView{ast->declarationList}) { + auto value = declaration(node); + } + + return {}; +} + +auto ASTInterpreter::privateModuleFragment(PrivateModuleFragmentAST* ast) + -> PrivateModuleFragmentResult { + if (!ast) return {}; + + for (auto node : ListView{ast->declarationList}) { + auto value = declaration(node); + } + + return {}; +} + +auto ASTInterpreter::moduleDeclaration(ModuleDeclarationAST* ast) + -> ModuleDeclarationResult { + if (!ast) return {}; + + auto moduleNameResult = moduleName(ast->moduleName); + auto modulePartitionResult = modulePartition(ast->modulePartition); + + for (auto node : ListView{ast->attributeList}) { + auto value = attributeSpecifier(node); + } + + return {}; +} + +auto ASTInterpreter::moduleName(ModuleNameAST* ast) -> ModuleNameResult { + if (!ast) return {}; + + auto moduleQualifierResult = moduleQualifier(ast->moduleQualifier); + + return {}; +} + +auto ASTInterpreter::moduleQualifier(ModuleQualifierAST* ast) + -> ModuleQualifierResult { + if (!ast) return {}; + + auto moduleQualifierResult = moduleQualifier(ast->moduleQualifier); + + return {}; +} + +auto ASTInterpreter::modulePartition(ModulePartitionAST* ast) + -> ModulePartitionResult { + if (!ast) return {}; + + auto moduleNameResult = moduleName(ast->moduleName); + + return {}; +} + +auto ASTInterpreter::importName(ImportNameAST* ast) -> ImportNameResult { + if (!ast) return {}; + + auto modulePartitionResult = modulePartition(ast->modulePartition); + auto moduleNameResult = moduleName(ast->moduleName); + + return {}; +} + +auto ASTInterpreter::UnitVisitor::operator()(TranslationUnitAST* ast) + -> UnitResult { + for (auto node : ListView{ast->declarationList}) { + auto value = interp.declaration(node); + } + + return {}; +} + +auto ASTInterpreter::UnitVisitor::operator()(ModuleUnitAST* ast) -> UnitResult { + auto globalModuleFragmentResult = + interp.globalModuleFragment(ast->globalModuleFragment); + auto moduleDeclarationResult = + interp.moduleDeclaration(ast->moduleDeclaration); + + for (auto node : ListView{ast->declarationList}) { + auto value = interp.declaration(node); + } + + auto privateModuleFragmentResult = + interp.privateModuleFragment(ast->privateModuleFragment); + + return {}; +} + +} // namespace cxx From 33660f3d515a7e69d49496c38c0960deb8cbd6e1 Mon Sep 17 00:00:00 2001 From: Roberto Raggi Date: Wed, 27 Aug 2025 19:08:39 +0200 Subject: [PATCH 2/2] Add unit test for nested template class instantiations Signed-off-by: Roberto Raggi --- tests/unit_tests/sema/template_class_05.cc | 38 ++++++++++++++++++++++ 1 file changed, 38 insertions(+) create mode 100644 tests/unit_tests/sema/template_class_05.cc diff --git a/tests/unit_tests/sema/template_class_05.cc b/tests/unit_tests/sema/template_class_05.cc new file mode 100644 index 00000000..f3005eb7 --- /dev/null +++ b/tests/unit_tests/sema/template_class_05.cc @@ -0,0 +1,38 @@ +// RUN: %cxx -fcheck -dump-symbols %s | %filecheck %s + +template +struct Outer { + template + struct Inner { + T t; + U u; + }; +}; + +template struct Outer; + +template struct Outer::Inner; + +// clang-format off +// CHECK:namespace +// CHECK-NEXT: template class Outer> +// CHECK-NEXT: parameter typename<0, 0> T +// CHECK-NEXT: template class Inner> +// CHECK-NEXT: parameter typename<0, 1> U +// CHECK-NEXT: field type-param<0, 0> t +// CHECK-NEXT: field type-param<0, 1> u +// CHECK-NEXT: [specializations] +// CHECK-NEXT: class Outer +// CHECK-NEXT: template class Inner> +// CHECK-NEXT: parameter typename<0, 1> U +// CHECK-NEXT: field float t +// CHECK-NEXT: field type-param<0, 1> u +// CHECK-NEXT: class Outer +// CHECK-NEXT: template class Inner> +// CHECK-NEXT: parameter typename<0, 1> U +// CHECK-NEXT: field int t +// CHECK-NEXT: field type-param<0, 1> u +// CHECK-NEXT: [specializations] +// CHECK-NEXT: class Inner +// CHECK-NEXT: field int t +// CHECK-NEXT: field char u