From 760c1391c0d11289f85ed46635114869d6f614a0 Mon Sep 17 00:00:00 2001 From: "Leandro T. C. Melo" Date: Sun, 9 Nov 2025 20:32:13 -0300 Subject: [PATCH] fix binding of (function type) typdefs with params --- C/sema/DeclarationBinder_Declarators.cpp | 6 ++- C/sema/TypedefNameTypeResolver.cpp | 10 ++++ C/sema/TypedefNameTypeResolver.h | 1 + C/symbols/TagDeclaration_StructOrUnion.cpp | 24 +++++++++ C/symbols/TagDeclaration_StructOrUnion.h | 2 + C/tests/DeclarationBinderTester_1000_1999.cpp | 34 +++++++++++- C/tests/DeclarationBinderTester_3000_3999.cpp | 53 +++++++++++++++++-- 7 files changed, 124 insertions(+), 6 deletions(-) diff --git a/C/sema/DeclarationBinder_Declarators.cpp b/C/sema/DeclarationBinder_Declarators.cpp index 1bb2d0948..7df4204eb 100644 --- a/C/sema/DeclarationBinder_Declarators.cpp +++ b/C/sema/DeclarationBinder_Declarators.cpp @@ -217,9 +217,13 @@ SyntaxVisitor::Action DeclarationBinder::visit_AtSingleDeclarator_COMMON( SyntaxVisitor::Action DeclarationBinder::visitParameterDeclaration_AtDeclarator( const ParameterDeclarationSyntax* node) { - return visit_AtSingleDeclarator_COMMON( + auto inTydefDecltor = F_.inTydefDecltor_; + F_.inTydefDecltor_ = false; + auto action = visit_AtSingleDeclarator_COMMON( node, &DeclarationBinder::visitParameterDeclaration_AtEnd); + F_.inTydefDecltor_ = inTydefDecltor; + return action; } SyntaxVisitor::Action DeclarationBinder::visitFunctionDefinition_AtDeclarator( diff --git a/C/sema/TypedefNameTypeResolver.cpp b/C/sema/TypedefNameTypeResolver.cpp index c51778758..0b44f152e 100644 --- a/C/sema/TypedefNameTypeResolver.cpp +++ b/C/sema/TypedefNameTypeResolver.cpp @@ -54,6 +54,16 @@ SyntaxVisitor::Action TypedefNameTypeResolver::visitTypedefDeclaration( return Action::Skip; } +SyntaxVisitor::Action TypedefNameTypeResolver::visitParameterDeclaration( + const ParameterDeclarationSyntax* node) +{ + auto inTydefDecltor = inTydefDecltor_; + inTydefDecltor_ = false; + VISIT(node->declarator()); + inTydefDecltor_ = inTydefDecltor; + return Action::Skip; +} + SyntaxVisitor::Action TypedefNameTypeResolver::visitIdentifierDeclarator( const IdentifierDeclaratorSyntax* node) { diff --git a/C/sema/TypedefNameTypeResolver.h b/C/sema/TypedefNameTypeResolver.h index ff4c300ec..d1bcf1697 100644 --- a/C/sema/TypedefNameTypeResolver.h +++ b/C/sema/TypedefNameTypeResolver.h @@ -51,6 +51,7 @@ class PSY_C_INTERNAL_API TypedefNameTypeResolver final : protected SyntaxVisitor // Declarations // //--------------// virtual Action visitTypedefDeclaration(const TypedefDeclarationSyntax*) override; + virtual Action visitParameterDeclaration(const ParameterDeclarationSyntax*) override; /* Declarators */ virtual Action visitIdentifierDeclarator(const IdentifierDeclaratorSyntax*) override; diff --git a/C/symbols/TagDeclaration_StructOrUnion.cpp b/C/symbols/TagDeclaration_StructOrUnion.cpp index 0dd671fc3..37baea069 100644 --- a/C/symbols/TagDeclaration_StructOrUnion.cpp +++ b/C/symbols/TagDeclaration_StructOrUnion.cpp @@ -62,3 +62,27 @@ void StructOrUnionDeclarationSymbol::addField(const FieldDeclarationSymbol* fld) { addMember(fld); } + +namespace psy { +namespace C { + +PSY_C_API std::ostream& operator<<( + std::ostream& os, + const StructOrUnionDeclarationSymbol* struktOrUnion) +{ + if (!struktOrUnion) + return os << ""; + switch (struktOrUnion->kind()) { + case SymbolKind::StructDeclaration: + return os << struktOrUnion->asStructDeclaration(); + case SymbolKind::UnionDeclaration: + return os << struktOrUnion->asUnionDeclaration(); + default: + PSY_ASSERT_1(false); + break; + } + return os << ""; +} + +} // C +} // psy diff --git a/C/symbols/TagDeclaration_StructOrUnion.h b/C/symbols/TagDeclaration_StructOrUnion.h index f3cd84dc6..12997998a 100644 --- a/C/symbols/TagDeclaration_StructOrUnion.h +++ b/C/symbols/TagDeclaration_StructOrUnion.h @@ -61,6 +61,8 @@ class PSY_C_API StructOrUnionDeclarationSymbol : public TagDeclarationSymbol TagType* tagTy); }; +PSY_C_API std::ostream& operator<<(std::ostream& os, const StructOrUnionDeclarationSymbol* struktOrUnion); + } // C } // psy diff --git a/C/tests/DeclarationBinderTester_1000_1999.cpp b/C/tests/DeclarationBinderTester_1000_1999.cpp index c1f99a5b6..f7a2b71b2 100644 --- a/C/tests/DeclarationBinderTester_1000_1999.cpp +++ b/C/tests/DeclarationBinderTester_1000_1999.cpp @@ -737,8 +737,38 @@ void DeclarationBinderTester::case1136() .ty_.Basic(BasicTypeKind::Double))); } -void DeclarationBinderTester::case1137() {} -void DeclarationBinderTester::case1138() {} +void DeclarationBinderTester::case1137() +{ + bind("x ( * y ) ( double z ) ;", + Expectation() + .declaration(Decl() + .Object("y", SymbolKind::VariableDeclaration) + .ty_.Typedef("x") + .ty_.Derived(TypeKind::Function) + .ty_.addParam().Basic(BasicTypeKind::Double) + .ty_.Derived(TypeKind::Pointer)) + .declaration(Decl() + .Object("z", SymbolKind::ParameterDeclaration, ScopeKind::FunctionPrototype) + .ty_.Basic(BasicTypeKind::Double))); +} + +void DeclarationBinderTester::case1138() +{ + bind("x ( * y ) ( double * z ) ;", + Expectation() + .declaration(Decl() + .Object("y", SymbolKind::VariableDeclaration) + .ty_.Typedef("x") + .ty_.Derived(TypeKind::Function) + .ty_.addParam().Basic(BasicTypeKind::Double) + .ty_.atParam().Derived(TypeKind::Pointer) + .ty_.Derived(TypeKind::Pointer)) + .declaration(Decl() + .Object("z", SymbolKind::ParameterDeclaration, ScopeKind::FunctionPrototype) + .ty_.Basic(BasicTypeKind::Double) + .ty_.Derived(TypeKind::Pointer))); +} + void DeclarationBinderTester::case1139() {} void DeclarationBinderTester::case1140() {} void DeclarationBinderTester::case1141() {} diff --git a/C/tests/DeclarationBinderTester_3000_3999.cpp b/C/tests/DeclarationBinderTester_3000_3999.cpp index 15fcd59f4..ebb50cc7a 100644 --- a/C/tests/DeclarationBinderTester_3000_3999.cpp +++ b/C/tests/DeclarationBinderTester_3000_3999.cpp @@ -385,9 +385,56 @@ void DeclarationBinderTester::case3110() .ty_.Basic(BasicTypeKind::Int_S, CVR::Const))); } -void DeclarationBinderTester::case3111(){} -void DeclarationBinderTester::case3112(){} -void DeclarationBinderTester::case3113(){} +void DeclarationBinderTester::case3111() +{ + bind("typedef int ( * x ) ( double ) ;", + Expectation() + .declaration(Decl() + .Type("x") + .inNameSpace(NameSpace::OrdinaryIdentifiers) + .withScopeKind(ScopeKind::File) + .ty_.Basic(BasicTypeKind::Int_S) + .ty_.Derived(TypeKind::Function) + .ty_.addParam().Basic(BasicTypeKind::Double) + .ty_.Derived(TypeKind::Pointer))); +} + +void DeclarationBinderTester::case3112() +{ + bind("typedef int ( * x ) ( double p ) ;", + Expectation() + .declaration(Decl() + .Type("x") + .inNameSpace(NameSpace::OrdinaryIdentifiers) + .withScopeKind(ScopeKind::File) + .ty_.Basic(BasicTypeKind::Int_S) + .ty_.Derived(TypeKind::Function) + .ty_.addParam().Basic(BasicTypeKind::Double) + .ty_.Derived(TypeKind::Pointer))); +} + +void DeclarationBinderTester::case3113() +{ + bind("typedef int ( * x ) ( double ) , ( * y ) ( double ) ;", + Expectation() + .declaration(Decl() + .Type("x") + .inNameSpace(NameSpace::OrdinaryIdentifiers) + .withScopeKind(ScopeKind::File) + .ty_.Basic(BasicTypeKind::Int_S) + .ty_.Derived(TypeKind::Function) + .ty_.addParam().Basic(BasicTypeKind::Double) + .ty_.Derived(TypeKind::Pointer)) + .declaration(Decl() + .Type("y") + .inNameSpace(NameSpace::OrdinaryIdentifiers) + .withScopeKind(ScopeKind::File) + .ty_.Basic(BasicTypeKind::Int_S) + .ty_.Derived(TypeKind::Function) + .ty_.addParam().Basic(BasicTypeKind::Double) + .ty_.Derived(TypeKind::Pointer))); +} + void DeclarationBinderTester::case3114(){} void DeclarationBinderTester::case3115(){} void DeclarationBinderTester::case3116(){}