diff --git a/src/parser/cxx/decl_specs.cc b/src/parser/cxx/decl_specs.cc index 4d7dd4f8..7d6afd70 100644 --- a/src/parser/cxx/decl_specs.cc +++ b/src/parser/cxx/decl_specs.cc @@ -23,6 +23,7 @@ // cxx #include #include +#include #include #include @@ -31,6 +32,8 @@ namespace cxx { struct DeclSpecs::Visitor { DeclSpecs& specs; + [[nodiscard]] auto control() const -> Control* { return specs.control(); } + void operator()(GeneratedTypeSpecifierAST* ast); void operator()(TypedefSpecifierAST* ast); void operator()(FriendSpecifierAST* ast); @@ -71,75 +74,257 @@ struct DeclSpecs::Visitor { void DeclSpecs::Visitor::operator()(GeneratedTypeSpecifierAST* ast) {} -void DeclSpecs::Visitor::operator()(TypedefSpecifierAST* ast) {} +void DeclSpecs::Visitor::operator()(TypedefSpecifierAST* ast) { + specs.isTypedef = true; +} + +void DeclSpecs::Visitor::operator()(FriendSpecifierAST* ast) { + specs.isFriend = true; +} + +void DeclSpecs::Visitor::operator()(ConstevalSpecifierAST* ast) { + specs.isConsteval = true; +} + +void DeclSpecs::Visitor::operator()(ConstinitSpecifierAST* ast) { + specs.isConstinit = true; +} + +void DeclSpecs::Visitor::operator()(ConstexprSpecifierAST* ast) { + specs.isConstexpr = true; +} + +void DeclSpecs::Visitor::operator()(InlineSpecifierAST* ast) { + specs.isInline = true; +} + +void DeclSpecs::Visitor::operator()(StaticSpecifierAST* ast) { + specs.isStatic = true; +} + +void DeclSpecs::Visitor::operator()(ExternSpecifierAST* ast) { + specs.isExtern = true; +} + +void DeclSpecs::Visitor::operator()(ThreadLocalSpecifierAST* ast) { + specs.isThreadLocal = true; +} + +void DeclSpecs::Visitor::operator()(ThreadSpecifierAST* ast) { + specs.isThread = true; +} + +void DeclSpecs::Visitor::operator()(MutableSpecifierAST* ast) { + specs.isMutable = true; +} + +void DeclSpecs::Visitor::operator()(VirtualSpecifierAST* ast) { + specs.isVirtual = true; +} + +void DeclSpecs::Visitor::operator()(ExplicitSpecifierAST* ast) { + specs.isExplicit = true; +} + +void DeclSpecs::Visitor::operator()(AutoTypeSpecifierAST* ast) { + specs.typeSpecifier = ast; + specs.type = control()->getAutoType(); +} + +void DeclSpecs::Visitor::operator()(VoidTypeSpecifierAST* ast) { + specs.typeSpecifier = ast; + specs.type = control()->getVoidType(); +} + +void DeclSpecs::Visitor::operator()(SizeTypeSpecifierAST* ast) { + switch (ast->specifier) { + case TokenKind::T_SHORT: + specs.isShort = true; + break; -void DeclSpecs::Visitor::operator()(FriendSpecifierAST* ast) {} + case TokenKind::T_LONG: + if (specs.isLong) + specs.isLongLong = true; + else + specs.isLong = true; + break; -void DeclSpecs::Visitor::operator()(ConstevalSpecifierAST* ast) {} + default: + break; + } // switch +} -void DeclSpecs::Visitor::operator()(ConstinitSpecifierAST* ast) {} +void DeclSpecs::Visitor::operator()(SignTypeSpecifierAST* ast) { + switch (ast->specifier) { + case TokenKind::T_SIGNED: + specs.isSigned = true; + break; -void DeclSpecs::Visitor::operator()(ConstexprSpecifierAST* ast) {} + case TokenKind::T_UNSIGNED: + specs.isUnsigned = true; + break; -void DeclSpecs::Visitor::operator()(InlineSpecifierAST* ast) {} + default: + break; + } // switch +} -void DeclSpecs::Visitor::operator()(StaticSpecifierAST* ast) {} +void DeclSpecs::Visitor::operator()(VaListTypeSpecifierAST* ast) { + specs.typeSpecifier = ast; + specs.type = control()->getBuiltinVaListType(); +} -void DeclSpecs::Visitor::operator()(ExternSpecifierAST* ast) {} +void DeclSpecs::Visitor::operator()(IntegralTypeSpecifierAST* ast) { + specs.typeSpecifier = ast; + switch (ast->specifier) { + case TokenKind::T_CHAR: + specs.type = control()->getCharType(); + break; -void DeclSpecs::Visitor::operator()(ThreadLocalSpecifierAST* ast) {} + case TokenKind::T_CHAR8_T: + specs.type = control()->getChar8Type(); + break; -void DeclSpecs::Visitor::operator()(ThreadSpecifierAST* ast) {} + case TokenKind::T_CHAR16_T: + specs.type = control()->getChar16Type(); + break; -void DeclSpecs::Visitor::operator()(MutableSpecifierAST* ast) {} + case TokenKind::T_CHAR32_T: + specs.type = control()->getChar32Type(); + break; -void DeclSpecs::Visitor::operator()(VirtualSpecifierAST* ast) {} + case TokenKind::T_WCHAR_T: + specs.type = control()->getWideCharType(); + break; -void DeclSpecs::Visitor::operator()(ExplicitSpecifierAST* ast) {} + case TokenKind::T_BOOL: + specs.type = control()->getBoolType(); + break; -void DeclSpecs::Visitor::operator()(AutoTypeSpecifierAST* ast) {} + case TokenKind::T_INT: + specs.type = control()->getIntType(); + break; -void DeclSpecs::Visitor::operator()(VoidTypeSpecifierAST* ast) {} + case TokenKind::T___INT64: + // ### todo + break; -void DeclSpecs::Visitor::operator()(SizeTypeSpecifierAST* ast) {} + case TokenKind::T___INT128: + // ### todo + break; -void DeclSpecs::Visitor::operator()(SignTypeSpecifierAST* ast) {} + default: + break; + } // switch +} -void DeclSpecs::Visitor::operator()(VaListTypeSpecifierAST* ast) {} +void DeclSpecs::Visitor::operator()(FloatingPointTypeSpecifierAST* ast) { + specs.typeSpecifier = ast; + switch (ast->specifier) { + case TokenKind::T_FLOAT: + specs.type = control()->getFloatType(); + break; -void DeclSpecs::Visitor::operator()(IntegralTypeSpecifierAST* ast) {} + case TokenKind::T_DOUBLE: + specs.type = control()->getDoubleType(); + break; -void DeclSpecs::Visitor::operator()(FloatingPointTypeSpecifierAST* ast) {} + case TokenKind::T_LONG: + specs.type = control()->getLongDoubleType(); + break; -void DeclSpecs::Visitor::operator()(ComplexTypeSpecifierAST* ast) {} + case TokenKind::T___FLOAT80: + // ### todo + break; -void DeclSpecs::Visitor::operator()(NamedTypeSpecifierAST* ast) {} + case TokenKind::T___FLOAT128: + // ### todo + break; -void DeclSpecs::Visitor::operator()(AtomicTypeSpecifierAST* ast) {} + default: + break; + } // switch +} -void DeclSpecs::Visitor::operator()(UnderlyingTypeSpecifierAST* ast) {} +void DeclSpecs::Visitor::operator()(ComplexTypeSpecifierAST* ast) { + specs.typeSpecifier = ast; + specs.isComplex = true; +} -void DeclSpecs::Visitor::operator()(ElaboratedTypeSpecifierAST* ast) {} +void DeclSpecs::Visitor::operator()(NamedTypeSpecifierAST* ast) { + specs.typeSpecifier = ast; + if (ast->symbol) specs.type = ast->symbol->type(); +} -void DeclSpecs::Visitor::operator()(DecltypeAutoSpecifierAST* ast) {} +void DeclSpecs::Visitor::operator()(AtomicTypeSpecifierAST* ast) { + specs.typeSpecifier = ast; + // ### todo +} -void DeclSpecs::Visitor::operator()(DecltypeSpecifierAST* ast) {} +void DeclSpecs::Visitor::operator()(UnderlyingTypeSpecifierAST* ast) { + specs.typeSpecifier = ast; + + if (ast->typeId) { + if (auto enumType = type_cast(ast->typeId->type)) { + specs.type = enumType->underlyingType(); + } else if (auto scopedEnumType = + type_cast(ast->typeId->type)) { + specs.type = scopedEnumType->underlyingType(); + } else { + specs.type = + control()->getUnresolvedUnderlyingType(specs.unit, ast->typeId); + } + } +} + +void DeclSpecs::Visitor::operator()(ElaboratedTypeSpecifierAST* ast) { + specs.typeSpecifier = ast; + if (ast->symbol) specs.type = ast->symbol->type(); +} + +void DeclSpecs::Visitor::operator()(DecltypeAutoSpecifierAST* ast) { + specs.typeSpecifier = ast; + specs.type = control()->getDecltypeAutoType(); +} + +void DeclSpecs::Visitor::operator()(DecltypeSpecifierAST* ast) { + specs.typeSpecifier = ast; + specs.type = ast->type; +} void DeclSpecs::Visitor::operator()(PlaceholderTypeSpecifierAST* ast) {} -void DeclSpecs::Visitor::operator()(ConstQualifierAST* ast) {} +void DeclSpecs::Visitor::operator()(ConstQualifierAST* ast) { + specs.isConst = true; +} -void DeclSpecs::Visitor::operator()(VolatileQualifierAST* ast) {} +void DeclSpecs::Visitor::operator()(VolatileQualifierAST* ast) { + specs.isVolatile = true; +} -void DeclSpecs::Visitor::operator()(RestrictQualifierAST* ast) {} +void DeclSpecs::Visitor::operator()(RestrictQualifierAST* ast) { + specs.isRestrict = true; +} -void DeclSpecs::Visitor::operator()(EnumSpecifierAST* ast) {} +void DeclSpecs::Visitor::operator()(EnumSpecifierAST* ast) { + specs.typeSpecifier = ast; + if (ast->symbol) specs.type = ast->symbol->type(); +} -void DeclSpecs::Visitor::operator()(ClassSpecifierAST* ast) {} +void DeclSpecs::Visitor::operator()(ClassSpecifierAST* ast) { + specs.typeSpecifier = ast; + if (ast->symbol) specs.type = ast->symbol->type(); +} -void DeclSpecs::Visitor::operator()(TypenameSpecifierAST* ast) {} +void DeclSpecs::Visitor::operator()(TypenameSpecifierAST* ast) { + specs.typeSpecifier = ast; + // ### todo +} -void DeclSpecs::Visitor::operator()(SplicerTypeSpecifierAST* ast) {} +void DeclSpecs::Visitor::operator()(SplicerTypeSpecifierAST* ast) { + specs.typeSpecifier = ast; + // ### todo +} DeclSpecs::DeclSpecs(TranslationUnit* unit) : unit(unit) {} diff --git a/src/parser/cxx/parser.cc b/src/parser/cxx/parser.cc index 97f91cfb..b968e99d 100644 --- a/src/parser/cxx/parser.cc +++ b/src/parser/cxx/parser.cc @@ -5279,10 +5279,9 @@ auto Parser::parse_defining_type_specifier( if (parse_enum_specifier(yyast, specs)) { lookahead.commit(); - auto enumSpec = ast_cast(yyast); - - specs.setTypeSpecifier(yyast); - specs.type = enumSpec->symbol->type(); + if (auto enumSpec = ast_cast(yyast)) { + specs.accept(enumSpec); + } return true; } @@ -5291,8 +5290,8 @@ auto Parser::parse_defining_type_specifier( parse_class_specifier(classSpecifier, specs, templateDeclarations)) { lookahead.commit(); - specs.setTypeSpecifier(classSpecifier); - specs.type = classSpecifier->symbol->type(); + specs.accept(classSpecifier); + yyast = classSpecifier; return true; @@ -5548,7 +5547,7 @@ auto Parser::parse_decltype_specifier_type_specifier(SpecifierAST*& yyast, yyast = decltypeSpecifier; - specs.type = decltypeSpecifier->type; + specs.accept(decltypeSpecifier); return true; } @@ -5569,16 +5568,7 @@ auto Parser::parse_underlying_type_specifier(SpecifierAST*& yyast, expect(TokenKind::T_RPAREN, ast->rparenLoc); - if (ast->typeId) { - if (auto enumType = type_cast(ast->typeId->type)) { - specs.type = enumType->underlyingType(); - } else if (auto scopedEnumType = - type_cast(ast->typeId->type)) { - specs.type = scopedEnumType->underlyingType(); - } else { - specs.type = control_->getUnresolvedUnderlyingType(unit, ast->typeId); - } - } + specs.accept(ast); return true; } @@ -5624,77 +5614,37 @@ auto Parser::parse_primitive_type_specifier(SpecifierAST*& yyast, yyast = ast; ast->specifierLoc = consumeToken(); ast->specifier = unit->tokenKind(ast->specifierLoc); + specs.accept(ast); specs.type = control_->getBuiltinVaListType(); return true; } case TokenKind::T_CHAR: - makeIntegralTypeSpecifier(); - specs.type = control_->getCharType(); - return true; - case TokenKind::T_CHAR8_T: - makeIntegralTypeSpecifier(); - specs.type = control_->getChar8Type(); - return true; - case TokenKind::T_CHAR16_T: - makeIntegralTypeSpecifier(); - specs.type = control_->getChar16Type(); - return true; - case TokenKind::T_CHAR32_T: - makeIntegralTypeSpecifier(); - specs.type = control_->getChar32Type(); - return true; - case TokenKind::T_WCHAR_T: - makeIntegralTypeSpecifier(); - specs.type = control_->getWideCharType(); - return true; - case TokenKind::T_BOOL: - makeIntegralTypeSpecifier(); - specs.type = control_->getBoolType(); - return true; - case TokenKind::T_INT: - makeIntegralTypeSpecifier(); - specs.type = control_->getIntType(); - return true; - case TokenKind::T___INT64: - makeIntegralTypeSpecifier(); - return true; - case TokenKind::T___INT128: makeIntegralTypeSpecifier(); + specs.accept(yyast); return true; case TokenKind::T_FLOAT: - makeFloatingPointTypeSpecifier(); - specs.type = control_->getFloatType(); - return true; - case TokenKind::T_DOUBLE: - makeFloatingPointTypeSpecifier(); - specs.type = control_->getDoubleType(); - return true; - case TokenKind::T___FLOAT80: - makeFloatingPointTypeSpecifier(); - return true; - case TokenKind::T___FLOAT128: makeFloatingPointTypeSpecifier(); + specs.accept(yyast); return true; case TokenKind::T_VOID: { auto ast = make_node(pool_); yyast = ast; ast->voidLoc = consumeToken(); - specs.type = control_->getVoidType(); - + specs.accept(ast); return true; }