diff --git a/src/parser/cxx/name_lookup.cc b/src/parser/cxx/name_lookup.cc index a7e62325..ccb89565 100644 --- a/src/parser/cxx/name_lookup.cc +++ b/src/parser/cxx/name_lookup.cc @@ -84,6 +84,11 @@ auto Lookup::lookupHelper(Scope* scope, const Name* name, cache.insert(scope); for (auto symbol : scope->find(name)) { + if (auto u = symbol_cast(symbol); + u && u->target()) { + return u->target(); + } + return symbol; } @@ -185,6 +190,30 @@ auto Lookup::lookupType(NestedNameSpecifierAST* nestedNameSpecifier, return nullptr; } + case SymbolKind::kUsingDeclaration: { + auto usingDeclaration = + symbol_cast(nestedNameSpecifier->symbol); + + if (!usingDeclaration->target()) return nullptr; + + if (auto classSymbol = + symbol_cast(usingDeclaration->target())) { + return lookupTypeHelper(classSymbol->scope(), id, set); + } + + if (auto enumSymbol = + symbol_cast(usingDeclaration->target())) { + return lookupTypeHelper(enumSymbol->scope(), id, set); + } + + if (auto scopedEnumSymbol = + symbol_cast(usingDeclaration->target())) { + return lookupTypeHelper(scopedEnumSymbol->scope(), id, set); + } + + return nullptr; + } + default: return nullptr; } // swotch @@ -198,9 +227,9 @@ auto Lookup::lookupTypeHelper(Scope* scope, const Identifier* id, } for (auto candidate : scope->find(id)) { - if (candidate->isClassOrNamespace() || candidate->isEnumOrScopedEnum() || - candidate->isTypeAlias() || candidate->isTypeParameter()) + if (is_type(candidate) || candidate->isNamespace()) { return candidate; + } } if (auto classSymbol = symbol_cast(scope->owner())) { diff --git a/src/parser/cxx/parser.cc b/src/parser/cxx/parser.cc index e8270194..612ebdad 100644 --- a/src/parser/cxx/parser.cc +++ b/src/parser/cxx/parser.cc @@ -6588,20 +6588,6 @@ auto Parser::is_glvalue(ExpressionAST* expr) const -> bool { expr->valueCategory == ValueCategory::kXValue; } -auto Parser::is_type(Symbol* symbol) const -> bool { - if (!symbol) return false; - switch (symbol->kind()) { - case SymbolKind::kTypeParameter: - case SymbolKind::kTypeAlias: - case SymbolKind::kClass: - case SymbolKind::kEnum: - case SymbolKind::kScopedEnum: - return true; - default: - return false; - } // switch -} - auto Parser::is_template(Symbol* symbol) const -> bool { auto templateParameters = cxx::getTemplateParameters(symbol); return templateParameters != nullptr; @@ -8325,6 +8311,10 @@ auto Parser::parse_using_declarator(UsingDeclaratorAST*& yyast) -> bool { auto target = Lookup{scope_}.lookup(nestedNameSpecifier, name); + if (auto u = symbol_cast(target)) { + target = u->target(); + } + auto symbol = control_->newUsingDeclarationSymbol( scope_, unqualifiedId->firstSourceLocation()); diff --git a/src/parser/cxx/parser.h b/src/parser/cxx/parser.h index f43294fa..d2c5f728 100644 --- a/src/parser/cxx/parser.h +++ b/src/parser/cxx/parser.h @@ -851,7 +851,6 @@ class Parser final { [[nodiscard]] auto is_xvalue(ExpressionAST* expr) const -> bool; [[nodiscard]] auto is_glvalue(ExpressionAST* expr) const -> bool; - [[nodiscard]] auto is_type(Symbol* symbol) const -> bool; [[nodiscard]] auto is_template(Symbol* symbol) const -> bool; [[nodiscard]] auto is_constructor(Symbol* symbol) const -> bool; diff --git a/src/parser/cxx/symbols.cc b/src/parser/cxx/symbols.cc index 1b66738b..1146344a 100644 --- a/src/parser/cxx/symbols.cc +++ b/src/parser/cxx/symbols.cc @@ -631,4 +631,23 @@ void UsingDeclarationSymbol::setDeclarator(UsingDeclaratorAST* declarator) { declarator_ = declarator; } +bool is_type(Symbol* symbol) { + if (!symbol) return false; + switch (symbol->kind()) { + case SymbolKind::kTypeParameter: + case SymbolKind::kConstraintTypeParameter: + case SymbolKind::kTypeAlias: + case SymbolKind::kClass: + case SymbolKind::kEnum: + case SymbolKind::kScopedEnum: + return true; + case SymbolKind::kUsingDeclaration: { + auto usingDeclaration = symbol_cast(symbol); + return is_type(usingDeclaration->target()); + } + default: + return false; + } // switch +} + } // namespace cxx diff --git a/src/parser/cxx/symbols.h b/src/parser/cxx/symbols.h index f9b60c46..bbc59fe4 100644 --- a/src/parser/cxx/symbols.h +++ b/src/parser/cxx/symbols.h @@ -135,7 +135,7 @@ class Symbol { [[nodiscard]] auto next() const -> Symbol*; #define PROCESS_SYMBOL(S) \ - [[nodiscard]] auto is##S() const->bool { return kind_ == SymbolKind::k##S; } + [[nodiscard]] auto is##S() const -> bool { return kind_ == SymbolKind::k##S; } CXX_FOR_EACH_SYMBOL(PROCESS_SYMBOL) #undef PROCESS_SYMBOL @@ -715,6 +715,8 @@ class UsingDeclarationSymbol final : public Symbol { UsingDeclaratorAST* declarator_ = nullptr; }; +bool is_type(Symbol* symbol); + template auto visit(Visitor&& visitor, Symbol* symbol) { #define PROCESS_SYMBOL(S) \ @@ -731,7 +733,7 @@ auto visit(Visitor&& visitor, Symbol* symbol) { } #define PROCESS_SYMBOL(S) \ - inline auto is##S##Symbol(Symbol* symbol)->bool { \ + inline auto is##S##Symbol(Symbol* symbol) -> bool { \ return symbol && symbol->kind() == SymbolKind::k##S; \ }