diff --git a/packages/cxx-gen-ast/src/new_ast_rewriter_cc.ts b/packages/cxx-gen-ast/src/new_ast_rewriter_cc.ts index 27fad0ca..74bc31f6 100644 --- a/packages/cxx-gen-ast/src/new_ast_rewriter_cc.ts +++ b/packages/cxx-gen-ast/src/new_ast_rewriter_cc.ts @@ -128,7 +128,7 @@ export function new_ast_rewriter_cc({ `auto ${m.name}Decl = Decl{${specsAttr}Ctx, copy->${m.name}};` ); emit( - `auto ${m.name}Type = getDeclaratorType(translationUnit(), copy->${m.name}, ${specsAttr}Ctx.getType());` + `auto ${m.name}Type = getDeclaratorType(translationUnit(), copy->${m.name}, ${specsAttr}Ctx.type());` ); typeAttr = members.find( @@ -197,6 +197,17 @@ export function new_ast_rewriter_cc({ } // switch emit(` }`); + + // update the context if needed + switch (m.type) { + case "SpecifierAST": + emit(`${m.name}Ctx.finish();`); + break; + + default: + break; + } // switch + emit(); break; } diff --git a/src/parser/cxx/ast.h b/src/parser/cxx/ast.h index de2e048e..eaf5bdab 100644 --- a/src/parser/cxx/ast.h +++ b/src/parser/cxx/ast.h @@ -217,7 +217,7 @@ class MemInitializerAST : public AST { class NestedNameSpecifierAST : public AST { public: using AST::AST; - Symbol* symbol = nullptr; + ScopedSymbol* symbol = nullptr; }; class NewInitializerAST : public AST { diff --git a/src/parser/cxx/ast_rewriter.cc b/src/parser/cxx/ast_rewriter.cc index 3c84cd03..a7579b3d 100644 --- a/src/parser/cxx/ast_rewriter.cc +++ b/src/parser/cxx/ast_rewriter.cc @@ -1059,8 +1059,8 @@ auto ASTRewriter::operator()(InitDeclaratorAST* ast, const DeclSpecs& declSpecs) auto decl = Decl{declSpecs, copy->declarator}; - auto type = getDeclaratorType(translationUnit(), copy->declarator, - declSpecs.getType()); + auto type = + getDeclaratorType(translationUnit(), copy->declarator, declSpecs.type()); // ### fix scope if (binder_.scope() && binder_.scope()->isClassScope()) { @@ -1152,12 +1152,13 @@ auto ASTRewriter::operator()(TypeIdAST* ast) -> TypeIdAST* { typeSpecifierList = &(*typeSpecifierList)->next; typeSpecifierListCtx.accept(value); } + typeSpecifierListCtx.finish(); copy->declarator = operator()(ast->declarator); auto declaratorDecl = Decl{typeSpecifierListCtx, copy->declarator}; auto declaratorType = getDeclaratorType(translationUnit(), copy->declarator, - typeSpecifierListCtx.getType()); + typeSpecifierListCtx.type()); copy->type = declaratorType; return copy; @@ -1194,8 +1195,10 @@ auto ASTRewriter::operator()(BaseSpecifierAST* ast) -> BaseSpecifierAST* { copy->nestedNameSpecifier = operator()(ast->nestedNameSpecifier); copy->templateLoc = ast->templateLoc; copy->unqualifiedId = operator()(ast->unqualifiedId); + copy->ellipsisLoc = ast->ellipsisLoc; copy->isTemplateIntroduced = ast->isTemplateIntroduced; copy->isVirtual = ast->isVirtual; + copy->isVariadic = ast->isVariadic; copy->accessSpecifier = ast->accessSpecifier; copy->symbol = ast->symbol; @@ -1403,6 +1406,7 @@ auto ASTRewriter::DeclarationVisitor::operator()(SimpleDeclarationAST* ast) declSpecifierList = &(*declSpecifierList)->next; declSpecifierListCtx.accept(value); } + declSpecifierListCtx.finish(); for (auto initDeclaratorList = ©->initDeclaratorList; auto node : ListView{ast->initDeclaratorList}) { @@ -1614,6 +1618,7 @@ auto ASTRewriter::DeclarationVisitor::operator()(OpaqueEnumDeclarationAST* ast) typeSpecifierList = &(*typeSpecifierList)->next; typeSpecifierListCtx.accept(value); } + typeSpecifierListCtx.finish(); copy->emicolonLoc = ast->emicolonLoc; @@ -1639,12 +1644,13 @@ auto ASTRewriter::DeclarationVisitor::operator()(FunctionDefinitionAST* ast) declSpecifierList = &(*declSpecifierList)->next; declSpecifierListCtx.accept(value); } + declSpecifierListCtx.finish(); copy->declarator = rewrite(ast->declarator); auto declaratorDecl = Decl{declSpecifierListCtx, copy->declarator}; auto declaratorType = getDeclaratorType(translationUnit(), copy->declarator, - declSpecifierListCtx.getType()); + declSpecifierListCtx.type()); copy->requiresClause = rewrite(ast->requiresClause); copy->functionBody = rewrite(ast->functionBody); copy->symbol = ast->symbol; @@ -1878,12 +1884,13 @@ auto ASTRewriter::DeclarationVisitor::operator()(ParameterDeclarationAST* ast) typeSpecifierList = &(*typeSpecifierList)->next; typeSpecifierListCtx.accept(value); } + typeSpecifierListCtx.finish(); copy->declarator = rewrite(ast->declarator); auto declaratorDecl = Decl{typeSpecifierListCtx, copy->declarator}; auto declaratorType = getDeclaratorType(translationUnit(), copy->declarator, - typeSpecifierListCtx.getType()); + typeSpecifierListCtx.type()); copy->type = declaratorType; copy->equalLoc = ast->equalLoc; copy->expression = rewrite(ast->expression); @@ -1931,6 +1938,7 @@ auto ASTRewriter::DeclarationVisitor::operator()( declSpecifierList = &(*declSpecifierList)->next; declSpecifierListCtx.accept(value); } + declSpecifierListCtx.finish(); copy->refQualifierLoc = ast->refQualifierLoc; copy->lbracketLoc = ast->lbracketLoc; @@ -3034,12 +3042,13 @@ auto ASTRewriter::ExpressionVisitor::operator()(NewExpressionAST* ast) typeSpecifierList = &(*typeSpecifierList)->next; typeSpecifierListCtx.accept(value); } + typeSpecifierListCtx.finish(); copy->declarator = rewrite(ast->declarator); auto declaratorDecl = Decl{typeSpecifierListCtx, copy->declarator}; auto declaratorType = getDeclaratorType(translationUnit(), copy->declarator, - typeSpecifierListCtx.getType()); + typeSpecifierListCtx.type()); copy->rparenLoc = ast->rparenLoc; copy->newInitalizer = rewrite(ast->newInitalizer); @@ -3224,12 +3233,13 @@ auto ASTRewriter::ExpressionVisitor::operator()(ConditionExpressionAST* ast) declSpecifierList = &(*declSpecifierList)->next; declSpecifierListCtx.accept(value); } + declSpecifierListCtx.finish(); copy->declarator = rewrite(ast->declarator); auto declaratorDecl = Decl{declSpecifierListCtx, copy->declarator}; auto declaratorType = getDeclaratorType(translationUnit(), copy->declarator, - declSpecifierListCtx.getType()); + declSpecifierListCtx.type()); copy->initializer = rewrite(ast->initializer); copy->symbol = ast->symbol; @@ -3734,6 +3744,7 @@ auto ASTRewriter::SpecifierVisitor::operator()(EnumSpecifierAST* ast) typeSpecifierList = &(*typeSpecifierList)->next; typeSpecifierListCtx.accept(value); } + typeSpecifierListCtx.finish(); copy->lbraceLoc = ast->lbraceLoc; @@ -4498,12 +4509,13 @@ auto ASTRewriter::ExceptionDeclarationVisitor::operator()( typeSpecifierList = &(*typeSpecifierList)->next; typeSpecifierListCtx.accept(value); } + typeSpecifierListCtx.finish(); copy->declarator = rewrite(ast->declarator); auto declaratorDecl = Decl{typeSpecifierListCtx, copy->declarator}; auto declaratorType = getDeclaratorType(translationUnit(), copy->declarator, - typeSpecifierListCtx.getType()); + typeSpecifierListCtx.type()); return copy; } diff --git a/src/parser/cxx/binder.cc b/src/parser/cxx/binder.cc index 71dfc3b2..583a7ec7 100644 --- a/src/parser/cxx/binder.cc +++ b/src/parser/cxx/binder.cc @@ -104,7 +104,10 @@ auto Binder::enterBlock(SourceLocation loc) -> BlockSymbol* { } void Binder::bind(EnumSpecifierAST* ast, const DeclSpecs& underlyingTypeSpecs) { - const auto underlyingType = underlyingTypeSpecs.getType(); + const Type* underlyingType = control()->getIntType(); + + if (underlyingTypeSpecs.hasTypeOrSizeSpecifier()) + underlyingType = underlyingTypeSpecs.type(); const auto location = ast->unqualifiedId ? ast->unqualifiedId->firstSourceLocation() @@ -133,12 +136,13 @@ void Binder::bind(EnumSpecifierAST* ast, const DeclSpecs& underlyingTypeSpecs) { } } -void Binder::bind(ElaboratedTypeSpecifierAST* ast, DeclSpecs& declSpecs) { +void Binder::bind(ElaboratedTypeSpecifierAST* ast, DeclSpecs& declSpecs, + bool isDeclaration) { + const auto _ = ScopeGuard{this}; + auto className = get_name(control(), ast->unqualifiedId); const auto location = ast->unqualifiedId->firstSourceLocation(); - const auto _ = ScopeGuard{this}; - if (ast->nestedNameSpecifier) { auto parent = ast->nestedNameSpecifier->symbol; @@ -171,8 +175,8 @@ void Binder::bind(ElaboratedTypeSpecifierAST* ast, DeclSpecs& declSpecs) { ast->symbol = classSymbol; - declSpecs.type = ast->symbol->type(); declSpecs.setTypeSpecifier(ast); + declSpecs.setType(ast->symbol->type()); } void Binder::bind(ClassSpecifierAST* ast, DeclSpecs& declSpecs) { @@ -250,7 +254,7 @@ void Binder::bind(ClassSpecifierAST* ast, DeclSpecs& declSpecs) { ast->symbol = classSymbol; declSpecs.setTypeSpecifier(ast); - declSpecs.type = classSymbol->type(); + declSpecs.setType(classSymbol->type()); } void Binder::complete(ClassSpecifierAST* ast) { @@ -266,7 +270,7 @@ void Binder::complete(ClassSpecifierAST* ast) { void Binder::bind(ParameterDeclarationAST* ast, const Decl& decl, bool inTemplateParameters) { - ast->type = getDeclaratorType(unit_, ast->declarator, decl.specs.getType()); + ast->type = getDeclaratorType(unit_, ast->declarator, decl.specs.type()); if (auto declId = decl.declaratorId; declId && declId->unqualifiedId) { auto paramName = get_name(control(), declId->unqualifiedId); @@ -503,13 +507,13 @@ void Binder::bind(UsingDirectiveAST* ast) { } void Binder::bind(TypeIdAST* ast, const Decl& decl) { - ast->type = getDeclaratorType(unit_, ast->declarator, decl.specs.getType()); + ast->type = getDeclaratorType(unit_, ast->declarator, decl.specs.type()); } auto Binder::declareTypedef(DeclaratorAST* declarator, const Decl& decl) -> TypeAliasSymbol* { auto name = decl.getName(); - auto type = getDeclaratorType(unit_, declarator, decl.specs.getType()); + auto type = getDeclaratorType(unit_, declarator, decl.specs.type()); auto symbol = control()->newTypeAliasSymbol(scope(), decl.location()); symbol->setName(name); symbol->setType(type); @@ -520,7 +524,7 @@ auto Binder::declareTypedef(DeclaratorAST* declarator, const Decl& decl) auto Binder::declareFunction(DeclaratorAST* declarator, const Decl& decl) -> FunctionSymbol* { auto name = decl.getName(); - auto type = getDeclaratorType(unit_, declarator, decl.specs.getType()); + auto type = getDeclaratorType(unit_, declarator, decl.specs.type()); auto parentScope = scope(); @@ -573,7 +577,7 @@ auto Binder::declareFunction(DeclaratorAST* declarator, const Decl& decl) auto Binder::declareField(DeclaratorAST* declarator, const Decl& decl) -> FieldSymbol* { auto name = decl.getName(); - auto type = getDeclaratorType(unit_, declarator, decl.specs.getType()); + auto type = getDeclaratorType(unit_, declarator, decl.specs.type()); auto fieldSymbol = control()->newFieldSymbol(scope(), decl.location()); applySpecifiers(fieldSymbol, decl.specs); fieldSymbol->setName(name); @@ -590,7 +594,7 @@ auto Binder::declareVariable(DeclaratorAST* declarator, const Decl& decl) -> VariableSymbol* { auto name = decl.getName(); auto symbol = control()->newVariableSymbol(scope(), decl.location()); - auto type = getDeclaratorType(unit_, declarator, decl.specs.getType()); + auto type = getDeclaratorType(unit_, declarator, decl.specs.type()); applySpecifiers(symbol, decl.specs); symbol->setName(name); symbol->setType(type); @@ -648,6 +652,32 @@ auto Binder::isConstructor(Symbol* symbol) const -> bool { return true; } +auto Binder::resolveNestedNameSpecifier(Symbol* symbol) -> ScopedSymbol* { + if (auto classSymbol = symbol_cast(symbol)) return classSymbol; + + if (auto namespaceSymbol = symbol_cast(symbol)) + return namespaceSymbol; + + if (auto enumSymbol = symbol_cast(symbol)) return enumSymbol; + + if (auto scopedEnumSymbol = symbol_cast(symbol)) + return scopedEnumSymbol; + + if (auto typeAliasSymbol = symbol_cast(symbol)) { + if (auto classType = type_cast(typeAliasSymbol->type())) + return classType->symbol(); + + if (auto enumType = type_cast(typeAliasSymbol->type())) + return enumType->symbol(); + + if (auto scopedEnumType = + type_cast(typeAliasSymbol->type())) + return scopedEnumType->symbol(); + } + + return nullptr; +} + auto Binder::resolve(NestedNameSpecifierAST* nestedNameSpecifier, UnqualifiedIdAST* unqualifiedId, bool canInstantiate) -> Symbol* { diff --git a/src/parser/cxx/binder.h b/src/parser/cxx/binder.h index 28bdf7ed..b99f46d9 100644 --- a/src/parser/cxx/binder.h +++ b/src/parser/cxx/binder.h @@ -89,7 +89,8 @@ class Binder { void bind(EnumSpecifierAST* ast, const DeclSpecs& underlyingTypeSpec); - void bind(ElaboratedTypeSpecifierAST* ast, DeclSpecs& declSpecs); + void bind(ElaboratedTypeSpecifierAST* ast, DeclSpecs& declSpecs, + bool isDeclaration); void bind(ClassSpecifierAST* ast, DeclSpecs& declSpecs); @@ -135,6 +136,9 @@ class Binder { UnqualifiedIdAST* unqualifiedId, bool canInstantiate) -> Symbol*; + [[nodiscard]] auto resolveNestedNameSpecifier(Symbol* symbol) + -> ScopedSymbol*; + class ScopeGuard { public: Binder* p = nullptr; diff --git a/src/parser/cxx/decl_specs.cc b/src/parser/cxx/decl_specs.cc index 074d709e..d34e90f7 100644 --- a/src/parser/cxx/decl_specs.cc +++ b/src/parser/cxx/decl_specs.cc @@ -128,14 +128,14 @@ void DeclSpecs::Visitor::operator()(ExplicitSpecifierAST* ast) { } void DeclSpecs::Visitor::operator()(AutoTypeSpecifierAST* ast) { - specs.typeSpecifier = ast; - specs.type = control()->getAutoType(); + specs.typeSpecifier_ = ast; + specs.type_ = control()->getAutoType(); specs.isAuto = true; } void DeclSpecs::Visitor::operator()(VoidTypeSpecifierAST* ast) { - specs.typeSpecifier = ast; - specs.type = control()->getVoidType(); + specs.typeSpecifier_ = ast; + specs.type_ = control()->getVoidType(); } void DeclSpecs::Visitor::operator()(SizeTypeSpecifierAST* ast) { @@ -172,39 +172,39 @@ void DeclSpecs::Visitor::operator()(SignTypeSpecifierAST* ast) { } void DeclSpecs::Visitor::operator()(VaListTypeSpecifierAST* ast) { - specs.typeSpecifier = ast; - specs.type = control()->getBuiltinVaListType(); + specs.typeSpecifier_ = ast; + specs.type_ = control()->getBuiltinVaListType(); } void DeclSpecs::Visitor::operator()(IntegralTypeSpecifierAST* ast) { - specs.typeSpecifier = ast; + specs.typeSpecifier_ = ast; switch (ast->specifier) { case TokenKind::T_CHAR: - specs.type = control()->getCharType(); + specs.type_ = control()->getCharType(); break; case TokenKind::T_CHAR8_T: - specs.type = control()->getChar8Type(); + specs.type_ = control()->getChar8Type(); break; case TokenKind::T_CHAR16_T: - specs.type = control()->getChar16Type(); + specs.type_ = control()->getChar16Type(); break; case TokenKind::T_CHAR32_T: - specs.type = control()->getChar32Type(); + specs.type_ = control()->getChar32Type(); break; case TokenKind::T_WCHAR_T: - specs.type = control()->getWideCharType(); + specs.type_ = control()->getWideCharType(); break; case TokenKind::T_BOOL: - specs.type = control()->getBoolType(); + specs.type_ = control()->getBoolType(); break; case TokenKind::T_INT: - specs.type = control()->getIntType(); + specs.type_ = control()->getIntType(); break; case TokenKind::T___INT64: @@ -221,18 +221,18 @@ void DeclSpecs::Visitor::operator()(IntegralTypeSpecifierAST* ast) { } void DeclSpecs::Visitor::operator()(FloatingPointTypeSpecifierAST* ast) { - specs.typeSpecifier = ast; + specs.typeSpecifier_ = ast; switch (ast->specifier) { case TokenKind::T_FLOAT: - specs.type = control()->getFloatType(); + specs.type_ = control()->getFloatType(); break; case TokenKind::T_DOUBLE: - specs.type = control()->getDoubleType(); + specs.type_ = control()->getDoubleType(); break; case TokenKind::T_LONG: - specs.type = control()->getLongDoubleType(); + specs.type_ = control()->getLongDoubleType(); break; case TokenKind::T___FLOAT80: @@ -249,59 +249,59 @@ void DeclSpecs::Visitor::operator()(FloatingPointTypeSpecifierAST* ast) { } void DeclSpecs::Visitor::operator()(ComplexTypeSpecifierAST* ast) { - specs.typeSpecifier = ast; + specs.typeSpecifier_ = ast; specs.isComplex = true; } void DeclSpecs::Visitor::operator()(NamedTypeSpecifierAST* ast) { - specs.typeSpecifier = ast; + specs.typeSpecifier_ = ast; if (ast->symbol) - specs.type = ast->symbol->type(); + specs.type_ = ast->symbol->type(); else - specs.type = control()->getUnresolvedNameType( - specs.unit, ast->nestedNameSpecifier, ast->unqualifiedId); + specs.type_ = control()->getUnresolvedNameType( + specs.unit_, ast->nestedNameSpecifier, ast->unqualifiedId); } void DeclSpecs::Visitor::operator()(AtomicTypeSpecifierAST* ast) { - specs.typeSpecifier = ast; + specs.typeSpecifier_ = ast; // ### todo } void DeclSpecs::Visitor::operator()(UnderlyingTypeSpecifierAST* ast) { - specs.typeSpecifier = ast; + specs.typeSpecifier_ = ast; if (ast->typeId) { if (auto enumType = type_cast(ast->typeId->type)) { - specs.type = enumType->underlyingType(); + specs.type_ = enumType->underlyingType(); } else if (auto scopedEnumType = type_cast(ast->typeId->type)) { - specs.type = scopedEnumType->underlyingType(); + specs.type_ = scopedEnumType->underlyingType(); } else { - specs.type = - control()->getUnresolvedUnderlyingType(specs.unit, ast->typeId); + 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(); + specs.typeSpecifier_ = ast; + if (ast->symbol) specs.type_ = ast->symbol->type(); } void DeclSpecs::Visitor::operator()(DecltypeAutoSpecifierAST* ast) { - specs.typeSpecifier = ast; - specs.type = control()->getDecltypeAutoType(); + specs.typeSpecifier_ = ast; + specs.type_ = control()->getDecltypeAutoType(); specs.isDecltypeAuto = true; } void DeclSpecs::Visitor::operator()(DecltypeSpecifierAST* ast) { - specs.typeSpecifier = ast; - specs.type = ast->type; + specs.typeSpecifier_ = ast; + specs.type_ = ast->type; } void DeclSpecs::Visitor::operator()(PlaceholderTypeSpecifierAST* ast) { - specs.typeSpecifier = ast; + specs.typeSpecifier_ = ast; } void DeclSpecs::Visitor::operator()(ConstQualifierAST* ast) { @@ -317,124 +317,146 @@ void DeclSpecs::Visitor::operator()(RestrictQualifierAST* ast) { } void DeclSpecs::Visitor::operator()(EnumSpecifierAST* ast) { - specs.typeSpecifier = ast; - if (ast->symbol) specs.type = ast->symbol->type(); + specs.typeSpecifier_ = ast; + if (ast->symbol) specs.type_ = ast->symbol->type(); } void DeclSpecs::Visitor::operator()(ClassSpecifierAST* ast) { - specs.typeSpecifier = ast; - if (ast->symbol) specs.type = ast->symbol->type(); + specs.typeSpecifier_ = ast; + if (ast->symbol) specs.type_ = ast->symbol->type(); } void DeclSpecs::Visitor::operator()(TypenameSpecifierAST* ast) { - specs.typeSpecifier = ast; - specs.type = control()->getUnresolvedNameType( - specs.unit, ast->nestedNameSpecifier, ast->unqualifiedId); + specs.typeSpecifier_ = ast; + specs.type_ = control()->getUnresolvedNameType( + specs.unit_, ast->nestedNameSpecifier, ast->unqualifiedId); // ### todo } void DeclSpecs::Visitor::operator()(SplicerTypeSpecifierAST* ast) { - specs.typeSpecifier = ast; + specs.typeSpecifier_ = ast; // ### todo } -DeclSpecs::DeclSpecs(TranslationUnit* unit) : unit(unit) {} +DeclSpecs::DeclSpecs(TranslationUnit* unit) : unit_(unit) {} DeclSpecs::DeclSpecs(ASTRewriter* rewriter) - : rewriter(rewriter), unit(rewriter->translationUnit()) {} + : rewriter_(rewriter), unit_(rewriter->translationUnit()) {} -auto DeclSpecs::control() const -> Control* { return unit->control(); } +auto DeclSpecs::control() const -> Control* { return unit_->control(); } void DeclSpecs::accept(SpecifierAST* specifier) { if (!specifier) return; visit(Visitor{*this}, specifier); } -auto DeclSpecs::getType() const -> const Type* { - auto type = this->type; +auto DeclSpecs::type() const -> const Type* { + if (!finished_) { + cxx_runtime_error("DeclSpecs::finish() not called"); + } + + return type_; +} + +void DeclSpecs::setType(const Type* type) { type_ = type; } - if (!type || type == control()->getIntType()) { +void DeclSpecs::finish() { + if (finished_) { + cxx_runtime_error("DeclSpecs::finish() called twice"); + } + + finished_ = true; + if (!type_ || type_ == control()->getIntType()) { if (isLongLong && isUnsigned) - type = control()->getUnsignedLongLongIntType(); + type_ = control()->getUnsignedLongLongIntType(); else if (isLongLong) - type = control()->getLongLongIntType(); + type_ = control()->getLongLongIntType(); else if (isLong && isUnsigned) - type = control()->getUnsignedLongIntType(); + type_ = control()->getUnsignedLongIntType(); else if (isLong) - type = control()->getLongIntType(); + type_ = control()->getLongIntType(); else if (isShort && isUnsigned) - type = control()->getUnsignedShortIntType(); + type_ = control()->getUnsignedShortIntType(); else if (isShort) - type = control()->getShortIntType(); + type_ = control()->getShortIntType(); else if (isUnsigned) - type = control()->getUnsignedIntType(); + type_ = control()->getUnsignedIntType(); else if (isSigned) - type = control()->getIntType(); + type_ = control()->getIntType(); } - if (!type) return nullptr; + if (!type_) { + return; + } - if (type == control()->getDoubleType() && isLong) - type = control()->getLongDoubleType(); + if (type_ == control()->getDoubleType() && isLong) + type_ = control()->getLongDoubleType(); - if (isSigned && type == control()->getCharType()) - type = control()->getSignedCharType(); + if (isSigned && type_ == control()->getCharType()) + type_ = control()->getSignedCharType(); if (isUnsigned) { - switch (type->kind()) { + switch (type_->kind()) { case TypeKind::kChar: - type = control()->getUnsignedCharType(); + type_ = control()->getUnsignedCharType(); break; case TypeKind::kShortInt: - type = control()->getUnsignedShortIntType(); + type_ = control()->getUnsignedShortIntType(); break; case TypeKind::kInt: - type = control()->getUnsignedIntType(); + type_ = control()->getUnsignedIntType(); break; case TypeKind::kLongInt: - type = control()->getUnsignedLongIntType(); + type_ = control()->getUnsignedLongIntType(); break; case TypeKind::kLongLongInt: - type = control()->getUnsignedLongLongIntType(); + type_ = control()->getUnsignedLongLongIntType(); break; case TypeKind::kChar8: - type = control()->getUnsignedCharType(); + type_ = control()->getUnsignedCharType(); break; case TypeKind::kChar16: - type = control()->getUnsignedShortIntType(); + type_ = control()->getUnsignedShortIntType(); break; case TypeKind::kChar32: - type = control()->getUnsignedIntType(); + type_ = control()->getUnsignedIntType(); break; case TypeKind::kWideChar: - type = control()->getUnsignedIntType(); + type_ = control()->getUnsignedIntType(); break; default: break; } // switch } - if (isConst) type = control()->add_const(type); - if (isVolatile) type = control()->add_volatile(type); - - return type; + if (isConst) type_ = control()->add_const(type_); + if (isVolatile) type_ = control()->add_volatile(type_); } -auto DeclSpecs::hasTypeSpecifier() const -> bool { - if (typeSpecifier) return true; +auto DeclSpecs::hasTypeOrSizeSpecifier() const -> bool { + if (hasTypeSpecifier()) return true; if (isShort || isLong) return true; if (isSigned || isUnsigned) return true; return false; } +auto DeclSpecs::hasTypeSpecifier() const -> bool { + if (typeSpecifier_) return true; + return false; +} + +auto DeclSpecs::typeSpecifier() const -> SpecifierAST* { + return typeSpecifier_; +} + void DeclSpecs::setTypeSpecifier(SpecifierAST* specifier) { - typeSpecifier = specifier; + typeSpecifier_ = specifier; } -auto DeclSpecs::hasClassOrEnumSpecifier() const -> bool { - if (!typeSpecifier) return false; - switch (typeSpecifier->kind()) { +auto DeclSpecs::hasClassOrElaboratedTypeSpecifier() const -> bool { + if (!typeSpecifier_) return false; + switch (typeSpecifier_->kind()) { case ASTKind::ClassSpecifier: case ASTKind::EnumSpecifier: case ASTKind::ElaboratedTypeSpecifier: @@ -446,8 +468,8 @@ auto DeclSpecs::hasClassOrEnumSpecifier() const -> bool { } auto DeclSpecs::hasPlaceholderTypeSpecifier() const -> bool { - if (!typeSpecifier) return false; - switch (typeSpecifier->kind()) { + if (!typeSpecifier_) return false; + switch (typeSpecifier_->kind()) { case ASTKind::AutoTypeSpecifier: case ASTKind::DecltypeAutoSpecifier: case ASTKind::PlaceholderTypeSpecifier: diff --git a/src/parser/cxx/decl_specs.h b/src/parser/cxx/decl_specs.h index 3ca346b9..24227a40 100644 --- a/src/parser/cxx/decl_specs.h +++ b/src/parser/cxx/decl_specs.h @@ -32,26 +32,35 @@ class ASTRewriter; class DeclSpecs { struct Visitor; + const Type* type_ = nullptr; + SpecifierAST* typeSpecifier_ = nullptr; + ASTRewriter* rewriter_ = nullptr; + TranslationUnit* unit_ = nullptr; + bool finished_ = false; + public: explicit DeclSpecs(TranslationUnit* unit = nullptr); explicit DeclSpecs(ASTRewriter* rewriter); [[nodiscard]] auto control() const -> Control*; - [[nodiscard]] auto getType() const -> const Type*; + + void finish(); + + [[nodiscard]] auto type() const -> const Type*; + void setType(const Type* type); [[nodiscard]] auto hasTypeSpecifier() const -> bool; + + [[nodiscard]] auto typeSpecifier() const -> SpecifierAST*; void setTypeSpecifier(SpecifierAST* specifier); - [[nodiscard]] auto hasClassOrEnumSpecifier() const -> bool; + [[nodiscard]] auto hasTypeOrSizeSpecifier() const -> bool; + [[nodiscard]] auto hasClassOrElaboratedTypeSpecifier() const -> bool; [[nodiscard]] auto hasPlaceholderTypeSpecifier() const -> bool; void accept(SpecifierAST* specifier); - ASTRewriter* rewriter = nullptr; - TranslationUnit* unit = nullptr; TemplateDeclarationAST* templateHead = nullptr; - const Type* type = nullptr; - SpecifierAST* typeSpecifier = nullptr; bool isTypedef = false; bool isFriend = false; diff --git a/src/parser/cxx/name_lookup.cc b/src/parser/cxx/name_lookup.cc index 93b38624..3aff838b 100644 --- a/src/parser/cxx/name_lookup.cc +++ b/src/parser/cxx/name_lookup.cc @@ -31,57 +31,75 @@ namespace cxx { Lookup::Lookup(Scope* scope) : scope_(scope) {} -auto Lookup::unqualifiedLookup(const Name* name) const -> Symbol* { +auto Lookup::operator()(const Name* name, + const std::function& accept) const + -> Symbol* { + return lookup(nullptr, name, accept); +} + +auto Lookup::operator()(NestedNameSpecifierAST* nestedNameSpecifier, + const Name* name, + const std::function& accept) const + -> Symbol* { + return lookup(nestedNameSpecifier, name, accept); +} + +auto Lookup::unqualifiedLookup(const Name* name, + const std::function& accept) const + -> Symbol* { std::unordered_set cache; for (auto current = scope_; current; current = current->parent()) { - if (auto symbol = lookupHelper(current, name, cache)) { + if (auto symbol = lookupHelper(current, name, cache, accept)) { return symbol; } } return nullptr; } -auto Lookup::qualifiedLookup(Scope* scope, const Name* name) const -> Symbol* { +auto Lookup::qualifiedLookup(Scope* scope, const Name* name, + const std::function& accept) const + -> Symbol* { std::unordered_set cache; - return lookupHelper(scope, name, cache); + return lookupHelper(scope, name, cache, accept); } -auto Lookup::qualifiedLookup(Symbol* scopedSymbol, const Name* name) const +auto Lookup::qualifiedLookup(Symbol* scopedSymbol, const Name* name, + const std::function& accept) const -> Symbol* { if (!scopedSymbol) return nullptr; switch (scopedSymbol->kind()) { case SymbolKind::kNamespace: return qualifiedLookup( - symbol_cast(scopedSymbol)->scope(), name); + symbol_cast(scopedSymbol)->scope(), name, accept); case SymbolKind::kClass: return qualifiedLookup(symbol_cast(scopedSymbol)->scope(), - name); + name, accept); case SymbolKind::kEnum: return qualifiedLookup(symbol_cast(scopedSymbol)->scope(), - name); + name, accept); case SymbolKind::kScopedEnum: return qualifiedLookup( - symbol_cast(scopedSymbol)->scope(), name); + symbol_cast(scopedSymbol)->scope(), name, accept); case SymbolKind::kTypeAlias: { auto alias = symbol_cast(scopedSymbol); if (auto classType = type_cast(alias->type())) { auto classSymbol = classType->symbol(); - return qualifiedLookup(classSymbol->scope(), name); + return qualifiedLookup(classSymbol->scope(), name, accept); } if (auto enumType = type_cast(alias->type())) { auto enumSymbol = enumType->symbol(); - return qualifiedLookup(enumSymbol->scope(), name); + return qualifiedLookup(enumSymbol->scope(), name, accept); } if (auto scopedEnumType = type_cast(alias->type())) { auto scopedEnumSymbol = scopedEnumType->symbol(); - return qualifiedLookup(scopedEnumSymbol->scope(), name); + return qualifiedLookup(scopedEnumSymbol->scope(), name, accept); } return nullptr; @@ -93,15 +111,19 @@ auto Lookup::qualifiedLookup(Symbol* scopedSymbol, const Name* name) const } auto Lookup::lookup(NestedNameSpecifierAST* nestedNameSpecifier, - const Name* name) const -> Symbol* { + const Name* name, + const std::function& accept) const + -> Symbol* { if (!name) return nullptr; - if (!nestedNameSpecifier) return unqualifiedLookup(name); + if (!nestedNameSpecifier) return unqualifiedLookup(name, accept); if (!nestedNameSpecifier->symbol) return nullptr; - return qualifiedLookup(nestedNameSpecifier->symbol, name); + return qualifiedLookup(nestedNameSpecifier->symbol, name, accept); } auto Lookup::lookupHelper(Scope* scope, const Name* name, - std::unordered_set& cache) const -> Symbol* { + std::unordered_set& cache, + const std::function& accept) const + -> Symbol* { if (cache.contains(scope)) { return nullptr; } @@ -111,24 +133,28 @@ auto Lookup::lookupHelper(Scope* scope, const Name* name, for (auto symbol : scope->find(name)) { if (auto u = symbol_cast(symbol); u && u->target()) { - return u->target(); + if (!accept || accept(u->target())) { + return u->target(); + } } - return symbol; + if (!accept || accept(symbol)) { + return symbol; + } } if (auto classSymbol = symbol_cast(scope->owner())) { for (const auto& base : classSymbol->baseClasses()) { auto baseClass = symbol_cast(base->symbol()); if (!baseClass) continue; - if (auto symbol = lookupHelper(baseClass->scope(), name, cache)) { + if (auto symbol = lookupHelper(baseClass->scope(), name, cache, accept)) { return symbol; } } } for (auto u : scope->usingDirectives()) { - if (auto symbol = lookupHelper(u, name, cache)) { + if (auto symbol = lookupHelper(u, name, cache, accept)) { return symbol; } } diff --git a/src/parser/cxx/name_lookup.h b/src/parser/cxx/name_lookup.h index 4bf82190..73103366 100644 --- a/src/parser/cxx/name_lookup.h +++ b/src/parser/cxx/name_lookup.h @@ -22,6 +22,7 @@ #include #include +#include #include namespace cxx { @@ -30,17 +31,21 @@ class Lookup { public: explicit Lookup(Scope* scope); - [[nodiscard]] auto operator()(const Name* name) const -> Symbol* { - return lookup(nullptr, name); - } + [[nodiscard]] auto operator()( + const Name* name, const std::function& accept = {}) const + -> Symbol*; + + [[nodiscard]] auto operator()( + NestedNameSpecifierAST* nestedNameSpecifier, const Name* name, + const std::function& accept = {}) const -> Symbol*; - [[nodiscard]] auto operator()(NestedNameSpecifierAST* nestedNameSpecifier, - const Name* name) const -> Symbol* { - return lookup(nestedNameSpecifier, name); - } + [[nodiscard]] auto lookup( + NestedNameSpecifierAST* nestedNameSpecifier, const Name* name, + const std::function& accept = {}) const -> Symbol*; - [[nodiscard]] auto lookup(NestedNameSpecifierAST* nestedNameSpecifier, - const Name* name) const -> Symbol*; + [[nodiscard]] auto qualifiedLookup( + Scope* scope, const Name* name, + const std::function& accept = {}) const -> Symbol*; [[nodiscard]] auto lookupNamespace( NestedNameSpecifierAST* nestedNameSpecifier, const Identifier* id) const @@ -49,18 +54,18 @@ class Lookup { [[nodiscard]] auto lookupType(NestedNameSpecifierAST* nestedNameSpecifier, const Identifier* id) const -> Symbol*; - [[nodiscard]] auto qualifiedLookup(Scope* scope, const Name* name) const - -> Symbol*; - private: - [[nodiscard]] auto unqualifiedLookup(const Name* name) const -> Symbol*; + [[nodiscard]] auto unqualifiedLookup( + const Name* name, const std::function& accept) const + -> Symbol*; - [[nodiscard]] auto qualifiedLookup(Symbol* scopedSymbol, - const Name* name) const -> Symbol*; + [[nodiscard]] auto qualifiedLookup( + Symbol* scopedSymbol, const Name* name, + const std::function& accept) const -> Symbol*; - [[nodiscard]] auto lookupHelper(Scope* scope, const Name* name, - std::unordered_set& cache) const - -> Symbol*; + [[nodiscard]] auto lookupHelper( + Scope* scope, const Name* name, std::unordered_set& cache, + const std::function& accept) const -> Symbol*; [[nodiscard]] auto lookupNamespaceHelper( Scope* scope, const Identifier* id, std::unordered_set& set) const diff --git a/src/parser/cxx/parser.cc b/src/parser/cxx/parser.cc index b1a7d83f..3cf63bf5 100644 --- a/src/parser/cxx/parser.cc +++ b/src/parser/cxx/parser.cc @@ -972,7 +972,7 @@ auto Parser::parse_type_nested_name_specifier(NestedNameSpecifierAST*& yyast, ast->identifierLoc = identifierLoc; ast->identifier = identifier; ast->scopeLoc = scopeLoc; - ast->symbol = symbol; + ast->symbol = binder_.resolveNestedNameSpecifier(symbol); return true; } @@ -1048,12 +1048,14 @@ auto Parser::parse_template_nested_name_specifier( } if (isReferencingPrimaryTemplate) { - ast->symbol = templateId->primaryTemplateSymbol; + ast->symbol = + binder_.resolveNestedNameSpecifier(templateId->primaryTemplateSymbol); } } if (!ast->symbol && config().checkTypes) { - ast->symbol = binder_.instantiate(templateId); + ast->symbol = + binder_.resolveNestedNameSpecifier(binder_.instantiate(templateId)); } return true; @@ -3910,6 +3912,8 @@ auto Parser::parse_notypespec_function_definition( parse_optional_decl_specifier_seq_no_typespecs(); + specs.finish(); + if (!parse_notypespec_function_definition(yyast, declSpecifierList, specs)) return false; @@ -3929,7 +3933,7 @@ auto Parser::parse_type_or_forward_declaration( List* trailingAttributes = nullptr; (void)parse_attribute_specifier_seq(trailingAttributes); - if (!specs.hasClassOrEnumSpecifier()) return false; + if (!specs.hasClassOrElaboratedTypeSpecifier()) return false; SourceLocation semicolonLoc; if (!match(TokenKind::T_SEMICOLON, semicolonLoc)) return false; @@ -4032,7 +4036,7 @@ auto Parser::parse_simple_declaration(DeclarationAST*& yyast, if (!parse_decl_specifier_seq(declSpecifierList, specs)) return false; - if (!specs.hasTypeSpecifier()) return false; + if (!specs.hasTypeOrSizeSpecifier()) return false; lookahead.commit(); return true; }; @@ -4074,8 +4078,7 @@ auto Parser::parse_simple_declaration( auto _ = Binder::ScopeGuard{&binder_}; - auto functionType = - getDeclaratorType(unit, declarator, decl.specs.getType()); + auto functionType = getDeclaratorType(unit, declarator, decl.specs.type()); auto q = decl.getNestedNameSpecifier(); @@ -4218,7 +4221,7 @@ auto Parser::parse_notypespec_function_definition( parse_optional_attribute_specifier_seq(functionDeclarator->attributeList); - auto functionType = getDeclaratorType(unit, declarator, decl.specs.getType()); + auto functionType = getDeclaratorType(unit, declarator, decl.specs.type()); SourceLocation equalLoc; SourceLocation zeroLoc; @@ -4491,6 +4494,8 @@ auto Parser::parse_decl_specifier_seq(List*& yyast, specifier = nullptr; } + specs.finish(); + return true; } @@ -4659,12 +4664,14 @@ auto Parser::parse_type_specifier_seq(List*& yyast, it = &(*it)->next; } + specs.finish(); + return true; } auto Parser::parse_defining_type_specifier(SpecifierAST*& yyast, DeclSpecs& specs) -> bool { - if (!specs.no_class_or_enum_specs && !specs.typeSpecifier) { + if (!specs.no_class_or_enum_specs && !specs.hasTypeSpecifier()) { LookaheadParser lookahead{this}; if (parse_enum_specifier(yyast, specs)) { @@ -4728,6 +4735,8 @@ auto Parser::parse_defining_type_specifier_seq(List*& yyast, it = &(*it)->next; } + specs.finish(); + return true; } @@ -4737,7 +4746,7 @@ auto Parser::parse_simple_type_specifier(SpecifierAST*& yyast, DeclSpecs& specs) if (parse_sign_type_specifier(yyast, specs)) return true; if (parse_complex_type_specifier(yyast, specs)) return true; - if (specs.typeSpecifier) return false; + if (specs.hasTypeSpecifier()) return false; if (parse_primitive_type_specifier(yyast, specs)) return true; if (parse_placeholder_type_specifier(yyast, specs)) return true; @@ -5069,12 +5078,14 @@ auto Parser::parse_elaborated_enum_specifier(SpecifierAST*& yyast, ast->unqualifiedId = name; ast->classKey = TokenKind::T_ENUM; + specs.setTypeSpecifier(ast); + return true; } auto Parser::parse_elaborated_type_specifier(SpecifierAST*& yyast, DeclSpecs& specs) -> bool { - if (specs.typeSpecifier) return false; + if (specs.hasTypeOrSizeSpecifier()) return false; if (parse_elaborated_enum_specifier(yyast, specs)) return true; @@ -5105,26 +5116,22 @@ auto Parser::parse_elaborated_type_specifier(SpecifierAST*& yyast, ast->classKey = unit->tokenKind(classLoc); ast->isTemplateIntroduced = isTemplateIntroduced; - const Identifier* className = nullptr; - SimpleTemplateIdAST* templateId = nullptr; - - if (parse_simple_template_id(templateId)) { + if (SimpleTemplateIdAST* templateId = nullptr; + parse_simple_template_id(templateId)) { ast->unqualifiedId = templateId; - className = templateId->identifier; + + mark_maybe_template_name(templateId->identifier); } else { // if we reach here, we have a name-id NameIdAST* nameId = nullptr; (void)parse_name_id(nameId); ast->unqualifiedId = nameId; - className = nameId->identifier; } - binder_.bind(ast, specs); + const auto isDeclaration = lookat(TokenKind::T_SEMICOLON); - if (is_template(ast->symbol)) { - mark_maybe_template_name(className); - } + binder_.bind(ast, specs, isDeclaration); return true; } @@ -7614,10 +7621,17 @@ auto Parser::parse_member_declaration_helper(DeclarationAST*& yyast) -> bool { (void)parse_decl_specifier_seq_no_typespecs(declSpecifierList, specs); auto lookat_notypespec_function_definition = [&] { + auto declSpecs = specs; + declSpecs.finish(); + LookaheadParser lookahead{this}; - if (!parse_notypespec_function_definition(yyast, declSpecifierList, specs)) + + if (!parse_notypespec_function_definition(yyast, declSpecifierList, + declSpecs)) return false; + lookahead.commit(); + return true; }; @@ -7630,7 +7644,7 @@ auto Parser::parse_member_declaration_helper(DeclarationAST*& yyast) -> bool { (void)parse_decl_specifier_seq(*lastDeclSpecifier, specs); - if (!specs.hasTypeSpecifier()) return false; + if (!specs.hasTypeOrSizeSpecifier()) return false; if (SourceLocation semicolonLoc; match(TokenKind::T_SEMICOLON, semicolonLoc)) { @@ -9051,7 +9065,7 @@ auto Parser::parse_concept_definition(DeclarationAST*& yyast) -> bool { auto Parser::parse_splicer_specifier(SpecifierAST*& yyast, DeclSpecs& specs) -> bool { if (!config().reflect) return false; - if (specs.typeSpecifier) return false; + if (specs.hasTypeOrSizeSpecifier()) return false; LookaheadParser lookahead{this}; SourceLocation typenameLoc; match(TokenKind::T_TYPENAME, typenameLoc); @@ -9068,7 +9082,7 @@ auto Parser::parse_splicer_specifier(SpecifierAST*& yyast, DeclSpecs& specs) auto Parser::parse_typename_specifier(SpecifierAST*& yyast, DeclSpecs& specs) -> bool { - if (specs.typeSpecifier) return false; + if (specs.hasTypeOrSizeSpecifier()) return false; SourceLocation typenameLoc; NestedNameSpecifierAST* nestedNameSpecifier = nullptr;