|
38 | 38 | #include <algorithm> |
39 | 39 | #include <cstring> |
40 | 40 | #include <format> |
| 41 | +#include <ranges> |
41 | 42 |
|
42 | 43 | namespace cxx { |
43 | 44 |
|
@@ -6568,33 +6569,56 @@ auto Parser::parse_elaborated_type_specifier_helper( |
6568 | 6569 | SourceLocation templateLoc; |
6569 | 6570 | const auto isTemplateIntroduced = match(TokenKind::T_TEMPLATE, templateLoc); |
6570 | 6571 |
|
6571 | | - UnqualifiedIdAST* unqualifiedId = nullptr; |
| 6572 | + auto ast = make_node<ElaboratedTypeSpecifierAST>(pool_); |
| 6573 | + yyast = ast; |
| 6574 | + |
| 6575 | + ast->classLoc = classLoc; |
| 6576 | + ast->attributeList = attributes; |
| 6577 | + ast->nestedNameSpecifier = nestedNameSpecifier; |
| 6578 | + ast->templateLoc = templateLoc; |
| 6579 | + ast->classKey = unit->tokenKind(classLoc); |
| 6580 | + ast->isTemplateIntroduced = isTemplateIntroduced; |
| 6581 | + |
6572 | 6582 | const auto loc = currentLocation(); |
6573 | 6583 |
|
6574 | 6584 | if (lookat(TokenKind::T_IDENTIFIER, TokenKind::T_LESS)) { |
6575 | 6585 | if (SimpleTemplateIdAST* templateId = nullptr; parse_simple_template_id( |
6576 | 6586 | templateId, nestedNameSpecifier, isTemplateIntroduced)) { |
6577 | | - unqualifiedId = templateId; |
| 6587 | + ast->unqualifiedId = templateId; |
6578 | 6588 | } else { |
6579 | 6589 | parse_error(loc, "expected a template-id"); |
6580 | 6590 | } |
6581 | 6591 | } else if (NameIdAST* nameId = nullptr; parse_name_id(nameId)) { |
6582 | | - unqualifiedId = nameId; |
| 6592 | + ast->unqualifiedId = nameId; |
| 6593 | + |
6583 | 6594 | auto symbol = Lookup{scope_}(nestedNameSpecifier, nameId->identifier); |
6584 | | - } else { |
6585 | | - parse_error("expected a name"); |
6586 | | - } |
6587 | 6595 |
|
6588 | | - auto ast = make_node<ElaboratedTypeSpecifierAST>(pool_); |
6589 | | - yyast = ast; |
| 6596 | + auto class_symbols_view = std::views::filter(&Symbol::isClass); |
6590 | 6597 |
|
6591 | | - ast->classLoc = classLoc; |
6592 | | - ast->attributeList = attributes; |
6593 | | - ast->nestedNameSpecifier = nestedNameSpecifier; |
6594 | | - ast->templateLoc = templateLoc; |
6595 | | - ast->unqualifiedId = unqualifiedId; |
6596 | | - ast->classKey = unit->tokenKind(classLoc); |
6597 | | - ast->isTemplateIntroduced = isTemplateIntroduced; |
| 6598 | + auto enum_symbols_view = std::views::filter([](Symbol* symbol) { |
| 6599 | + return symbol->isEnum() || symbol->isScopedEnum(); |
| 6600 | + }); |
| 6601 | + |
| 6602 | + if (ast->classKey == TokenKind::T_CLASS || |
| 6603 | + ast->classKey == TokenKind::T_STRUCT || |
| 6604 | + ast->classKey == TokenKind::T_UNION) { |
| 6605 | + for (auto symbol : SymbolChainView(symbol) | class_symbols_view) { |
| 6606 | + if (symbol->name() != nameId->identifier) continue; |
| 6607 | + ast->symbol = symbol; |
| 6608 | + specs.type = symbol->type(); |
| 6609 | + break; |
| 6610 | + } |
| 6611 | + } else if (ast->classKey == TokenKind::T_ENUM) { |
| 6612 | + for (auto symbol : SymbolChainView(symbol) | enum_symbols_view) { |
| 6613 | + if (symbol->name() != nameId->identifier) continue; |
| 6614 | + ast->symbol = symbol; |
| 6615 | + specs.type = symbol->type(); |
| 6616 | + break; |
| 6617 | + } |
| 6618 | + } |
| 6619 | + } else { |
| 6620 | + parse_error(loc, "expected a name"); |
| 6621 | + } |
6598 | 6622 |
|
6599 | 6623 | return true; |
6600 | 6624 | } |
|
0 commit comments