...
diff --git a/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/diagnostics/LLFirDiagnosticVisitor.kt b/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/diagnostics/LLFirDiagnosticVisitor.kt
index 1e2a5d9..9cc35ee 100644
--- a/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/diagnostics/LLFirDiagnosticVisitor.kt
+++ b/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/diagnostics/LLFirDiagnosticVisitor.kt
@@ -18,6 +18,7 @@
 import org.jetbrains.kotlin.fir.analysis.collectors.DiagnosticCollectorComponents
 import org.jetbrains.kotlin.fir.declarations.*
 import org.jetbrains.kotlin.fir.psi
+import org.jetbrains.kotlin.fir.visitors.FirCompositeVisitor
 import org.jetbrains.kotlin.psi.KtCodeFragment
 import org.jetbrains.kotlin.psi.KtDeclaration
 import org.jetbrains.kotlin.utils.exceptions.rethrowIntellijPlatformExceptionIfNeeded
@@ -28,6 +29,8 @@
 ) : CheckerRunningDiagnosticCollectorVisitor(context, components) {
     private val beforeElementDiagnosticCollectionHandler = context.session.beforeElementDiagnosticCollectionHandler
 
+    private val visitor = FirCompositeVisitor(components.regularComponents)
+
     override fun visitNestedElements(element: FirElement) {
         if (element is FirDeclaration) {
             beforeElementDiagnosticCollectionHandler?.beforeGoingNestedDeclaration(element, context)
@@ -38,11 +41,9 @@
 
     override fun checkElement(element: FirElement) {
         beforeElementDiagnosticCollectionHandler?.beforeCollectingForElement(element)
-        components.regularComponents.forEach { diagnosticVisitor ->
-            checkCanceled()
-            suppressAndLogExceptions {
-                element.accept(diagnosticVisitor, context)
-            }
+        checkCanceled()
+        suppressAndLogExceptions {
+            element.accept(visitor, context)
         }
 
         checkCanceled()
diff --git a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/collectors/CheckerRunningDiagnosticCollectorVisitor.kt b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/collectors/CheckerRunningDiagnosticCollectorVisitor.kt
index 1a7658c..a64df07 100644
--- a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/collectors/CheckerRunningDiagnosticCollectorVisitor.kt
+++ b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/collectors/CheckerRunningDiagnosticCollectorVisitor.kt
@@ -9,20 +9,21 @@
 import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContextForProvider
 import org.jetbrains.kotlin.fir.declarations.FirDeclaration
 import org.jetbrains.kotlin.fir.declarations.FirFile
+import org.jetbrains.kotlin.fir.visitors.FirCompositeVisitor
 
 open class CheckerRunningDiagnosticCollectorVisitor(
     context: CheckerContextForProvider,
     protected val components: DiagnosticCollectorComponents
 ) : AbstractDiagnosticCollectorVisitor(context) {
 
+    private val visitor = FirCompositeVisitor(components.regularComponents)
+
     override fun checkSettings() {
         components.regularComponents.forEach { it.checkSettings(context) }
     }
 
     override fun checkElement(element: FirElement) {
-        components.regularComponents.forEach {
-            element.accept(it, context)
-        }
+        element.accept(visitor, context)
         element.accept(components.reportCommitter, context)
     }
 
diff --git a/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/visitors/FirCompositeVisitor.kt b/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/visitors/FirCompositeVisitor.kt
new file mode 100644
index 0000000..9f3267d
--- /dev/null
+++ b/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/visitors/FirCompositeVisitor.kt
@@ -0,0 +1,645 @@
+/*
+ * Copyright 2010-2024 JetBrains s.r.o. and Kotlin Programming Language contributors.
+ * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
+ */
+
+// This file was generated automatically. See compiler/fir/tree/tree-generator/Readme.md.
+// DO NOT MODIFY IT MANUALLY.
+
+package org.jetbrains.kotlin.fir.visitors
+
+import org.jetbrains.kotlin.fir.*
+import org.jetbrains.kotlin.fir.contracts.*
+import org.jetbrains.kotlin.fir.declarations.*
+import org.jetbrains.kotlin.fir.diagnostics.FirDiagnosticHolder
+import org.jetbrains.kotlin.fir.expressions.*
+import org.jetbrains.kotlin.fir.references.*
+import org.jetbrains.kotlin.fir.types.*
+
+/**
+ * Auto-generated by [org.jetbrains.kotlin.fir.tree.generator.printer.CompositeVisitorPrinter]
+ */
+class FirCompositeVisitor<in D>(
+    val visitors: Array<out FirVisitor<Unit, D>>,
+) : FirVisitor<Unit, D>() {
+
+    override fun visitElement(element: FirElement, data: D) {
+        visitors.forEach { it.visitElement(element, data) }
+    }
+
+    override fun visitAnnotationContainer(annotationContainer: FirAnnotationContainer, data: D) {
+        visitors.forEach { it.visitAnnotationContainer(annotationContainer, data) }
+    }
+
+    override fun visitTypeParameterRef(typeParameterRef: FirTypeParameterRef, data: D) {
+        visitors.forEach { it.visitTypeParameterRef(typeParameterRef, data) }
+    }
+
+    override fun visitTypeParametersOwner(typeParametersOwner: FirTypeParametersOwner, data: D) {
+        visitors.forEach { it.visitTypeParametersOwner(typeParametersOwner, data) }
+    }
+
+    override fun visitTypeParameterRefsOwner(typeParameterRefsOwner: FirTypeParameterRefsOwner, data: D) {
+        visitors.forEach { it.visitTypeParameterRefsOwner(typeParameterRefsOwner, data) }
+    }
+
+    override fun visitResolvable(resolvable: FirResolvable, data: D) {
+        visitors.forEach { it.visitResolvable(resolvable, data) }
+    }
+
+    override fun visitDiagnosticHolder(diagnosticHolder: FirDiagnosticHolder, data: D) {
+        visitors.forEach { it.visitDiagnosticHolder(diagnosticHolder, data) }
+    }
+
+    override fun visitControlFlowGraphOwner(controlFlowGraphOwner: FirControlFlowGraphOwner, data: D) {
+        visitors.forEach { it.visitControlFlowGraphOwner(controlFlowGraphOwner, data) }
+    }
+
+    override fun visitElementWithResolveState(elementWithResolveState: FirElementWithResolveState, data: D) {
+        visitors.forEach { it.visitElementWithResolveState(elementWithResolveState, data) }
+    }
+
+    override fun visitDeclaration(declaration: FirDeclaration, data: D) {
+        visitors.forEach { it.visitDeclaration(declaration, data) }
+    }
+
+    override fun visitCallableDeclaration(callableDeclaration: FirCallableDeclaration, data: D) {
+        visitors.forEach { it.visitCallableDeclaration(callableDeclaration, data) }
+    }
+
+    override fun visitFunction(function: FirFunction, data: D) {
+        visitors.forEach { it.visitFunction(function, data) }
+    }
+
+    override fun visitErrorExpression(errorExpression: FirErrorExpression, data: D) {
+        visitors.forEach { it.visitErrorExpression(errorExpression, data) }
+    }
+
+    override fun visitErrorFunction(errorFunction: FirErrorFunction, data: D) {
+        visitors.forEach { it.visitErrorFunction(errorFunction, data) }
+    }
+
+    override fun visitMemberDeclaration(memberDeclaration: FirMemberDeclaration, data: D) {
+        visitors.forEach { it.visitMemberDeclaration(memberDeclaration, data) }
+    }
+
+    override fun visitStatement(statement: FirStatement, data: D) {
+        visitors.forEach { it.visitStatement(statement, data) }
+    }
+
+    override fun visitExpression(expression: FirExpression, data: D) {
+        visitors.forEach { it.visitExpression(expression, data) }
+    }
+
+    override fun visitLazyExpression(lazyExpression: FirLazyExpression, data: D) {
+        visitors.forEach { it.visitLazyExpression(lazyExpression, data) }
+    }
+
+    override fun visitArgumentList(argumentList: FirArgumentList, data: D) {
+        visitors.forEach { it.visitArgumentList(argumentList, data) }
+    }
+
+    override fun visitCall(call: FirCall, data: D) {
+        visitors.forEach { it.visitCall(call, data) }
+    }
+
+    override fun visitBlock(block: FirBlock, data: D) {
+        visitors.forEach { it.visitBlock(block, data) }
+    }
+
+    override fun visitLazyBlock(lazyBlock: FirLazyBlock, data: D) {
+        visitors.forEach { it.visitLazyBlock(lazyBlock, data) }
+    }
+
+    override fun visitBooleanOperatorExpression(booleanOperatorExpression: FirBooleanOperatorExpression, data: D) {
+        visitors.forEach { it.visitBooleanOperatorExpression(booleanOperatorExpression, data) }
+    }
+
+    override fun visitTargetElement(targetElement: FirTargetElement, data: D) {
+        visitors.forEach { it.visitTargetElement(targetElement, data) }
+    }
+
+    override fun <E : FirTargetElement> visitJump(jump: FirJump<E>, data: D) {
+        visitors.forEach { it.visitJump(jump, data) }
+    }
+
+    override fun visitLoopJump(loopJump: FirLoopJump, data: D) {
+        visitors.forEach { it.visitLoopJump(loopJump, data) }
+    }
+
+    override fun visitBreakExpression(breakExpression: FirBreakExpression, data: D) {
+        visitors.forEach { it.visitBreakExpression(breakExpression, data) }
+    }
+
+    override fun visitContinueExpression(continueExpression: FirContinueExpression, data: D) {
+        visitors.forEach { it.visitContinueExpression(continueExpression, data) }
+    }
+
+    override fun visitReturnExpression(returnExpression: FirReturnExpression, data: D) {
+        visitors.forEach { it.visitReturnExpression(returnExpression, data) }
+    }
+
+    override fun visitLabel(label: FirLabel, data: D) {
+        visitors.forEach { it.visitLabel(label, data) }
+    }
+
+    override fun visitLoop(loop: FirLoop, data: D) {
+        visitors.forEach { it.visitLoop(loop, data) }
+    }
+
+    override fun visitWhileLoop(whileLoop: FirWhileLoop, data: D) {
+        visitors.forEach { it.visitWhileLoop(whileLoop, data) }
+    }
+
+    override fun visitDoWhileLoop(doWhileLoop: FirDoWhileLoop, data: D) {
+        visitors.forEach { it.visitDoWhileLoop(doWhileLoop, data) }
+    }
+
+    override fun visitErrorLoop(errorLoop: FirErrorLoop, data: D) {
+        visitors.forEach { it.visitErrorLoop(errorLoop, data) }
+    }
+
+    override fun visitCatch(catch: FirCatch, data: D) {
+        visitors.forEach { it.visitCatch(catch, data) }
+    }
+
+    override fun visitTryExpression(tryExpression: FirTryExpression, data: D) {
+        visitors.forEach { it.visitTryExpression(tryExpression, data) }
+    }
+
+    override fun visitElvisExpression(elvisExpression: FirElvisExpression, data: D) {
+        visitors.forEach { it.visitElvisExpression(elvisExpression, data) }
+    }
+
+    override fun visitContextArgumentListOwner(contextArgumentListOwner: FirContextArgumentListOwner, data: D) {
+        visitors.forEach { it.visitContextArgumentListOwner(contextArgumentListOwner, data) }
+    }
+
+    override fun visitQualifiedAccessExpression(qualifiedAccessExpression: FirQualifiedAccessExpression, data: D) {
+        visitors.forEach { it.visitQualifiedAccessExpression(qualifiedAccessExpression, data) }
+    }
+
+    override fun visitQualifiedErrorAccessExpression(qualifiedErrorAccessExpression: FirQualifiedErrorAccessExpression, data: D) {
+        visitors.forEach { it.visitQualifiedErrorAccessExpression(qualifiedErrorAccessExpression, data) }
+    }
+
+    override fun visitLiteralExpression(literalExpression: FirLiteralExpression, data: D) {
+        visitors.forEach { it.visitLiteralExpression(literalExpression, data) }
+    }
+
+    override fun visitFunctionCall(functionCall: FirFunctionCall, data: D) {
+        visitors.forEach { it.visitFunctionCall(functionCall, data) }
+    }
+
+    override fun visitIntegerLiteralOperatorCall(integerLiteralOperatorCall: FirIntegerLiteralOperatorCall, data: D) {
+        visitors.forEach { it.visitIntegerLiteralOperatorCall(integerLiteralOperatorCall, data) }
+    }
+
+    override fun visitArrayLiteral(arrayLiteral: FirArrayLiteral, data: D) {
+        visitors.forEach { it.visitArrayLiteral(arrayLiteral, data) }
+    }
+
+    override fun visitCheckNotNullCall(checkNotNullCall: FirCheckNotNullCall, data: D) {
+        visitors.forEach { it.visitCheckNotNullCall(checkNotNullCall, data) }
+    }
+
+    override fun visitComparisonExpression(comparisonExpression: FirComparisonExpression, data: D) {
+        visitors.forEach { it.visitComparisonExpression(comparisonExpression, data) }
+    }
+
+    override fun visitTypeOperatorCall(typeOperatorCall: FirTypeOperatorCall, data: D) {
+        visitors.forEach { it.visitTypeOperatorCall(typeOperatorCall, data) }
+    }
+
+    override fun visitAugmentedAssignment(augmentedAssignment: FirAugmentedAssignment, data: D) {
+        visitors.forEach { it.visitAugmentedAssignment(augmentedAssignment, data) }
+    }
+
+    override fun visitIncrementDecrementExpression(incrementDecrementExpression: FirIncrementDecrementExpression, data: D) {
+        visitors.forEach { it.visitIncrementDecrementExpression(incrementDecrementExpression, data) }
+    }
+
+    override fun visitEqualityOperatorCall(equalityOperatorCall: FirEqualityOperatorCall, data: D) {
+        visitors.forEach { it.visitEqualityOperatorCall(equalityOperatorCall, data) }
+    }
+
+    override fun visitWhenBranch(whenBranch: FirWhenBranch, data: D) {
+        visitors.forEach { it.visitWhenBranch(whenBranch, data) }
+    }
+
+    override fun visitClassLikeDeclaration(classLikeDeclaration: FirClassLikeDeclaration, data: D) {
+        visitors.forEach { it.visitClassLikeDeclaration(classLikeDeclaration, data) }
+    }
+
+    override fun visitClass(klass: FirClass, data: D) {
+        visitors.forEach { it.visitClass(klass, data) }
+    }
+
+    override fun visitRegularClass(regularClass: FirRegularClass, data: D) {
+        visitors.forEach { it.visitRegularClass(regularClass, data) }
+    }
+
+    override fun visitAnonymousObject(anonymousObject: FirAnonymousObject, data: D) {
+        visitors.forEach { it.visitAnonymousObject(anonymousObject, data) }
+    }
+
+    override fun visitAnonymousObjectExpression(anonymousObjectExpression: FirAnonymousObjectExpression, data: D) {
+        visitors.forEach { it.visitAnonymousObjectExpression(anonymousObjectExpression, data) }
+    }
+
+    override fun visitTypeAlias(typeAlias: FirTypeAlias, data: D) {
+        visitors.forEach { it.visitTypeAlias(typeAlias, data) }
+    }
+
+    override fun visitAnonymousFunction(anonymousFunction: FirAnonymousFunction, data: D) {
+        visitors.forEach { it.visitAnonymousFunction(anonymousFunction, data) }
+    }
+
+    override fun visitAnonymousFunctionExpression(anonymousFunctionExpression: FirAnonymousFunctionExpression, data: D) {
+        visitors.forEach { it.visitAnonymousFunctionExpression(anonymousFunctionExpression, data) }
+    }
+
+    override fun visitTypeParameter(typeParameter: FirTypeParameter, data: D) {
+        visitors.forEach { it.visitTypeParameter(typeParameter, data) }
+    }
+
+    override fun visitConstructedClassTypeParameterRef(constructedClassTypeParameterRef: FirConstructedClassTypeParameterRef, data: D) {
+        visitors.forEach { it.visitConstructedClassTypeParameterRef(constructedClassTypeParameterRef, data) }
+    }
+
+    override fun visitOuterClassTypeParameterRef(outerClassTypeParameterRef: FirOuterClassTypeParameterRef, data: D) {
+        visitors.forEach { it.visitOuterClassTypeParameterRef(outerClassTypeParameterRef, data) }
+    }
+
+    override fun visitSimpleFunction(simpleFunction: FirSimpleFunction, data: D) {
+        visitors.forEach { it.visitSimpleFunction(simpleFunction, data) }
+    }
+
+    override fun visitContractDescriptionOwner(contractDescriptionOwner: FirContractDescriptionOwner, data: D) {
+        visitors.forEach { it.visitContractDescriptionOwner(contractDescriptionOwner, data) }
+    }
+
+    override fun visitProperty(property: FirProperty, data: D) {
+        visitors.forEach { it.visitProperty(property, data) }
+    }
+
+    override fun visitPropertyAccessor(propertyAccessor: FirPropertyAccessor, data: D) {
+        visitors.forEach { it.visitPropertyAccessor(propertyAccessor, data) }
+    }
+
+    override fun visitBackingField(backingField: FirBackingField, data: D) {
+        visitors.forEach { it.visitBackingField(backingField, data) }
+    }
+
+    override fun visitDeclarationStatus(declarationStatus: FirDeclarationStatus, data: D) {
+        visitors.forEach { it.visitDeclarationStatus(declarationStatus, data) }
+    }
+
+    override fun visitResolvedDeclarationStatus(resolvedDeclarationStatus: FirResolvedDeclarationStatus, data: D) {
+        visitors.forEach { it.visitResolvedDeclarationStatus(resolvedDeclarationStatus, data) }
+    }
+
+    override fun visitImplicitInvokeCall(implicitInvokeCall: FirImplicitInvokeCall, data: D) {
+        visitors.forEach { it.visitImplicitInvokeCall(implicitInvokeCall, data) }
+    }
+
+    override fun visitConstructor(constructor: FirConstructor, data: D) {
+        visitors.forEach { it.visitConstructor(constructor, data) }
+    }
+
+    override fun visitErrorPrimaryConstructor(errorPrimaryConstructor: FirErrorPrimaryConstructor, data: D) {
+        visitors.forEach { it.visitErrorPrimaryConstructor(errorPrimaryConstructor, data) }
+    }
+
+    override fun visitDelegatedConstructorCall(delegatedConstructorCall: FirDelegatedConstructorCall, data: D) {
+        visitors.forEach { it.visitDelegatedConstructorCall(delegatedConstructorCall, data) }
+    }
+
+    override fun visitMultiDelegatedConstructorCall(multiDelegatedConstructorCall: FirMultiDelegatedConstructorCall, data: D) {
+        visitors.forEach { it.visitMultiDelegatedConstructorCall(multiDelegatedConstructorCall, data) }
+    }
+
+    override fun visitValueParameter(valueParameter: FirValueParameter, data: D) {
+        visitors.forEach { it.visitValueParameter(valueParameter, data) }
+    }
+
+    override fun visitReceiverParameter(receiverParameter: FirReceiverParameter, data: D) {
+        visitors.forEach { it.visitReceiverParameter(receiverParameter, data) }
+    }
+
+    override fun visitScriptReceiverParameter(scriptReceiverParameter: FirScriptReceiverParameter, data: D) {
+        visitors.forEach { it.visitScriptReceiverParameter(scriptReceiverParameter, data) }
+    }
+
+    override fun visitVariable(variable: FirVariable, data: D) {
+        visitors.forEach { it.visitVariable(variable, data) }
+    }
+
+    override fun visitFunctionTypeParameter(functionTypeParameter: FirFunctionTypeParameter, data: D) {
+        visitors.forEach { it.visitFunctionTypeParameter(functionTypeParameter, data) }
+    }
+
+    override fun visitErrorProperty(errorProperty: FirErrorProperty, data: D) {
+        visitors.forEach { it.visitErrorProperty(errorProperty, data) }
+    }
+
+    override fun visitEnumEntry(enumEntry: FirEnumEntry, data: D) {
+        visitors.forEach { it.visitEnumEntry(enumEntry, data) }
+    }
+
+    override fun visitField(field: FirField, data: D) {
+        visitors.forEach { it.visitField(field, data) }
+    }
+
+    override fun visitAnonymousInitializer(anonymousInitializer: FirAnonymousInitializer, data: D) {
+        visitors.forEach { it.visitAnonymousInitializer(anonymousInitializer, data) }
+    }
+
+    override fun visitDanglingModifierList(danglingModifierList: FirDanglingModifierList, data: D) {
+        visitors.forEach { it.visitDanglingModifierList(danglingModifierList, data) }
+    }
+
+    override fun visitFile(file: FirFile, data: D) {
+        visitors.forEach { it.visitFile(file, data) }
+    }
+
+    override fun visitScript(script: FirScript, data: D) {
+        visitors.forEach { it.visitScript(script, data) }
+    }
+
+    override fun visitCodeFragment(codeFragment: FirCodeFragment, data: D) {
+        visitors.forEach { it.visitCodeFragment(codeFragment, data) }
+    }
+
+    override fun visitReplSnippet(replSnippet: FirReplSnippet, data: D) {
+        visitors.forEach { it.visitReplSnippet(replSnippet, data) }
+    }
+
+    override fun visitPackageDirective(packageDirective: FirPackageDirective, data: D) {
+        visitors.forEach { it.visitPackageDirective(packageDirective, data) }
+    }
+
+    override fun visitImport(import: FirImport, data: D) {
+        visitors.forEach { it.visitImport(import, data) }
+    }
+
+    override fun visitResolvedImport(resolvedImport: FirResolvedImport, data: D) {
+        visitors.forEach { it.visitResolvedImport(resolvedImport, data) }
+    }
+
+    override fun visitAnnotation(annotation: FirAnnotation, data: D) {
+        visitors.forEach { it.visitAnnotation(annotation, data) }
+    }
+
+    override fun visitAnnotationCall(annotationCall: FirAnnotationCall, data: D) {
+        visitors.forEach { it.visitAnnotationCall(annotationCall, data) }
+    }
+
+    override fun visitErrorAnnotationCall(errorAnnotationCall: FirErrorAnnotationCall, data: D) {
+        visitors.forEach { it.visitErrorAnnotationCall(errorAnnotationCall, data) }
+    }
+
+    override fun visitAnnotationArgumentMapping(annotationArgumentMapping: FirAnnotationArgumentMapping, data: D) {
+        visitors.forEach { it.visitAnnotationArgumentMapping(annotationArgumentMapping, data) }
+    }
+
+    override fun visitIndexedAccessAugmentedAssignment(indexedAccessAugmentedAssignment: FirIndexedAccessAugmentedAssignment, data: D) {
+        visitors.forEach { it.visitIndexedAccessAugmentedAssignment(indexedAccessAugmentedAssignment, data) }
+    }
+
+    override fun visitClassReferenceExpression(classReferenceExpression: FirClassReferenceExpression, data: D) {
+        visitors.forEach { it.visitClassReferenceExpression(classReferenceExpression, data) }
+    }
+
+    override fun visitComponentCall(componentCall: FirComponentCall, data: D) {
+        visitors.forEach { it.visitComponentCall(componentCall, data) }
+    }
+
+    override fun visitSmartCastExpression(smartCastExpression: FirSmartCastExpression, data: D) {
+        visitors.forEach { it.visitSmartCastExpression(smartCastExpression, data) }
+    }
+
+    override fun visitSafeCallExpression(safeCallExpression: FirSafeCallExpression, data: D) {
+        visitors.forEach { it.visitSafeCallExpression(safeCallExpression, data) }
+    }
+
+    override fun visitCheckedSafeCallSubject(checkedSafeCallSubject: FirCheckedSafeCallSubject, data: D) {
+        visitors.forEach { it.visitCheckedSafeCallSubject(checkedSafeCallSubject, data) }
+    }
+
+    override fun visitCallableReferenceAccess(callableReferenceAccess: FirCallableReferenceAccess, data: D) {
+        visitors.forEach { it.visitCallableReferenceAccess(callableReferenceAccess, data) }
+    }
+
+    override fun visitPropertyAccessExpression(propertyAccessExpression: FirPropertyAccessExpression, data: D) {
+        visitors.forEach { it.visitPropertyAccessExpression(propertyAccessExpression, data) }
+    }
+
+    override fun visitGetClassCall(getClassCall: FirGetClassCall, data: D) {
+        visitors.forEach { it.visitGetClassCall(getClassCall, data) }
+    }
+
+    override fun visitWrappedArgumentExpression(wrappedArgumentExpression: FirWrappedArgumentExpression, data: D) {
+        visitors.forEach { it.visitWrappedArgumentExpression(wrappedArgumentExpression, data) }
+    }
+
+    override fun visitSpreadArgumentExpression(spreadArgumentExpression: FirSpreadArgumentExpression, data: D) {
+        visitors.forEach { it.visitSpreadArgumentExpression(spreadArgumentExpression, data) }
+    }
+
+    override fun visitNamedArgumentExpression(namedArgumentExpression: FirNamedArgumentExpression, data: D) {
+        visitors.forEach { it.visitNamedArgumentExpression(namedArgumentExpression, data) }
+    }
+
+    override fun visitVarargArgumentsExpression(varargArgumentsExpression: FirVarargArgumentsExpression, data: D) {
+        visitors.forEach { it.visitVarargArgumentsExpression(varargArgumentsExpression, data) }
+    }
+
+    override fun visitSamConversionExpression(samConversionExpression: FirSamConversionExpression, data: D) {
+        visitors.forEach { it.visitSamConversionExpression(samConversionExpression, data) }
+    }
+
+    override fun visitResolvedQualifier(resolvedQualifier: FirResolvedQualifier, data: D) {
+        visitors.forEach { it.visitResolvedQualifier(resolvedQualifier, data) }
+    }
+
+    override fun visitErrorResolvedQualifier(errorResolvedQualifier: FirErrorResolvedQualifier, data: D) {
+        visitors.forEach { it.visitErrorResolvedQualifier(errorResolvedQualifier, data) }
+    }
+
+    override fun visitResolvedReifiedParameterReference(resolvedReifiedParameterReference: FirResolvedReifiedParameterReference, data: D) {
+        visitors.forEach { it.visitResolvedReifiedParameterReference(resolvedReifiedParameterReference, data) }
+    }
+
+    override fun visitStringConcatenationCall(stringConcatenationCall: FirStringConcatenationCall, data: D) {
+        visitors.forEach { it.visitStringConcatenationCall(stringConcatenationCall, data) }
+    }
+
+    override fun visitThrowExpression(throwExpression: FirThrowExpression, data: D) {
+        visitors.forEach { it.visitThrowExpression(throwExpression, data) }
+    }
+
+    override fun visitVariableAssignment(variableAssignment: FirVariableAssignment, data: D) {
+        visitors.forEach { it.visitVariableAssignment(variableAssignment, data) }
+    }
+
+    override fun visitWhenSubjectExpression(whenSubjectExpression: FirWhenSubjectExpression, data: D) {
+        visitors.forEach { it.visitWhenSubjectExpression(whenSubjectExpression, data) }
+    }
+
+    override fun visitDesugaredAssignmentValueReferenceExpression(desugaredAssignmentValueReferenceExpression: FirDesugaredAssignmentValueReferenceExpression, data: D) {
+        visitors.forEach { it.visitDesugaredAssignmentValueReferenceExpression(desugaredAssignmentValueReferenceExpression, data) }
+    }
+
+    override fun visitWrappedExpression(wrappedExpression: FirWrappedExpression, data: D) {
+        visitors.forEach { it.visitWrappedExpression(wrappedExpression, data) }
+    }
+
+    override fun visitWrappedDelegateExpression(wrappedDelegateExpression: FirWrappedDelegateExpression, data: D) {
+        visitors.forEach { it.visitWrappedDelegateExpression(wrappedDelegateExpression, data) }
+    }
+
+    override fun visitEnumEntryDeserializedAccessExpression(enumEntryDeserializedAccessExpression: FirEnumEntryDeserializedAccessExpression, data: D) {
+        visitors.forEach { it.visitEnumEntryDeserializedAccessExpression(enumEntryDeserializedAccessExpression, data) }
+    }
+
+    override fun visitReference(reference: FirReference, data: D) {
+        visitors.forEach { it.visitReference(reference, data) }
+    }
+
+    override fun visitNamedReference(namedReference: FirNamedReference, data: D) {
+        visitors.forEach { it.visitNamedReference(namedReference, data) }
+    }
+
+    override fun visitNamedReferenceWithCandidateBase(namedReferenceWithCandidateBase: FirNamedReferenceWithCandidateBase, data: D) {
+        visitors.forEach { it.visitNamedReferenceWithCandidateBase(namedReferenceWithCandidateBase, data) }
+    }
+
+    override fun visitResolvedNamedReference(resolvedNamedReference: FirResolvedNamedReference, data: D) {
+        visitors.forEach { it.visitResolvedNamedReference(resolvedNamedReference, data) }
+    }
+
+    override fun visitResolvedCallableReference(resolvedCallableReference: FirResolvedCallableReference, data: D) {
+        visitors.forEach { it.visitResolvedCallableReference(resolvedCallableReference, data) }
+    }
+
+    override fun visitDelegateFieldReference(delegateFieldReference: FirDelegateFieldReference, data: D) {
+        visitors.forEach { it.visitDelegateFieldReference(delegateFieldReference, data) }
+    }
+
+    override fun visitBackingFieldReference(backingFieldReference: FirBackingFieldReference, data: D) {
+        visitors.forEach { it.visitBackingFieldReference(backingFieldReference, data) }
+    }
+
+    override fun visitSuperReference(superReference: FirSuperReference, data: D) {
+        visitors.forEach { it.visitSuperReference(superReference, data) }
+    }
+
+    override fun visitThisReference(thisReference: FirThisReference, data: D) {
+        visitors.forEach { it.visitThisReference(thisReference, data) }
+    }
+
+    override fun visitControlFlowGraphReference(controlFlowGraphReference: FirControlFlowGraphReference, data: D) {
+        visitors.forEach { it.visitControlFlowGraphReference(controlFlowGraphReference, data) }
+    }
+
+    override fun visitTypeRef(typeRef: FirTypeRef, data: D) {
+        visitors.forEach { it.visitTypeRef(typeRef, data) }
+    }
+
+    override fun visitResolvedTypeRef(resolvedTypeRef: FirResolvedTypeRef, data: D) {
+        visitors.forEach { it.visitResolvedTypeRef(resolvedTypeRef, data) }
+    }
+
+    override fun visitUnresolvedTypeRef(unresolvedTypeRef: FirUnresolvedTypeRef, data: D) {
+        visitors.forEach { it.visitUnresolvedTypeRef(unresolvedTypeRef, data) }
+    }
+
+    override fun visitUserTypeRef(userTypeRef: FirUserTypeRef, data: D) {
+        visitors.forEach { it.visitUserTypeRef(userTypeRef, data) }
+    }
+
+    override fun visitFunctionTypeRef(functionTypeRef: FirFunctionTypeRef, data: D) {
+        visitors.forEach { it.visitFunctionTypeRef(functionTypeRef, data) }
+    }
+
+    override fun visitDynamicTypeRef(dynamicTypeRef: FirDynamicTypeRef, data: D) {
+        visitors.forEach { it.visitDynamicTypeRef(dynamicTypeRef, data) }
+    }
+
+    override fun visitImplicitTypeRef(implicitTypeRef: FirImplicitTypeRef, data: D) {
+        visitors.forEach { it.visitImplicitTypeRef(implicitTypeRef, data) }
+    }
+
+    override fun visitErrorTypeRef(errorTypeRef: FirErrorTypeRef, data: D) {
+        visitors.forEach { it.visitErrorTypeRef(errorTypeRef, data) }
+    }
+
+    override fun visitResolvedErrorReference(resolvedErrorReference: FirResolvedErrorReference, data: D) {
+        visitors.forEach { it.visitResolvedErrorReference(resolvedErrorReference, data) }
+    }
+
+    override fun visitErrorNamedReference(errorNamedReference: FirErrorNamedReference, data: D) {
+        visitors.forEach { it.visitErrorNamedReference(errorNamedReference, data) }
+    }
+
+    override fun visitIntersectionTypeRef(intersectionTypeRef: FirIntersectionTypeRef, data: D) {
+        visitors.forEach { it.visitIntersectionTypeRef(intersectionTypeRef, data) }
+    }
+
+    override fun visitThisReceiverExpression(thisReceiverExpression: FirThisReceiverExpression, data: D) {
+        visitors.forEach { it.visitThisReceiverExpression(thisReceiverExpression, data) }
+    }
+
+    override fun visitInaccessibleReceiverExpression(inaccessibleReceiverExpression: FirInaccessibleReceiverExpression, data: D) {
+        visitors.forEach { it.visitInaccessibleReceiverExpression(inaccessibleReceiverExpression, data) }
+    }
+
+    override fun visitWhenExpression(whenExpression: FirWhenExpression, data: D) {
+        visitors.forEach { it.visitWhenExpression(whenExpression, data) }
+    }
+
+    override fun visitTypeProjection(typeProjection: FirTypeProjection, data: D) {
+        visitors.forEach { it.visitTypeProjection(typeProjection, data) }
+    }
+
+    override fun visitTypeProjectionWithVariance(typeProjectionWithVariance: FirTypeProjectionWithVariance, data: D) {
+        visitors.forEach { it.visitTypeProjectionWithVariance(typeProjectionWithVariance, data) }
+    }
+
+    override fun visitStarProjection(starProjection: FirStarProjection, data: D) {
+        visitors.forEach { it.visitStarProjection(starProjection, data) }
+    }
+
+    override fun visitPlaceholderProjection(placeholderProjection: FirPlaceholderProjection, data: D) {
+        visitors.forEach { it.visitPlaceholderProjection(placeholderProjection, data) }
+    }
+
+    override fun visitContractElementDeclaration(contractElementDeclaration: FirContractElementDeclaration, data: D) {
+        visitors.forEach { it.visitContractElementDeclaration(contractElementDeclaration, data) }
+    }
+
+    override fun visitEffectDeclaration(effectDeclaration: FirEffectDeclaration, data: D) {
+        visitors.forEach { it.visitEffectDeclaration(effectDeclaration, data) }
+    }
+
+    override fun visitContractDescription(contractDescription: FirContractDescription, data: D) {
+        visitors.forEach { it.visitContractDescription(contractDescription, data) }
+    }
+
+    override fun visitRawContractDescription(rawContractDescription: FirRawContractDescription, data: D) {
+        visitors.forEach { it.visitRawContractDescription(rawContractDescription, data) }
+    }
+
+    override fun visitResolvedContractDescription(resolvedContractDescription: FirResolvedContractDescription, data: D) {
+        visitors.forEach { it.visitResolvedContractDescription(resolvedContractDescription, data) }
+    }
+
+    override fun visitLegacyRawContractDescription(legacyRawContractDescription: FirLegacyRawContractDescription, data: D) {
+        visitors.forEach { it.visitLegacyRawContractDescription(legacyRawContractDescription, data) }
+    }
+
+    override fun visitErrorContractDescription(errorContractDescription: FirErrorContractDescription, data: D) {
+        visitors.forEach { it.visitErrorContractDescription(errorContractDescription, data) }
+    }
+}
diff --git a/compiler/fir/tree/tree-generator/src/org/jetbrains/kotlin/fir/tree/generator/Main.kt b/compiler/fir/tree/tree-generator/src/org/jetbrains/kotlin/fir/tree/generator/Main.kt
index f9e86f4..1f87a0c 100644
--- a/compiler/fir/tree/tree-generator/src/org/jetbrains/kotlin/fir/tree/generator/Main.kt
+++ b/compiler/fir/tree/tree-generator/src/org/jetbrains/kotlin/fir/tree/generator/Main.kt
@@ -32,6 +32,7 @@
                 firVisitorVoidType to ::VisitorVoidPrinter,
                 firDefaultVisitorVoidType to ::DefaultVisitorVoidPrinter,
                 firTransformerType to ::TransformerPrinter.bind(model.rootElement),
+                firCompositeVisitorType to ::CompositeVisitorPrinter,
             ),
             ImplementationConfigurator,
             BuilderConfigurator(model),
diff --git a/compiler/fir/tree/tree-generator/src/org/jetbrains/kotlin/fir/tree/generator/Types.kt b/compiler/fir/tree/tree-generator/src/org/jetbrains/kotlin/fir/tree/generator/Types.kt
index d29a685..eb36f11 100644
--- a/compiler/fir/tree/tree-generator/src/org/jetbrains/kotlin/fir/tree/generator/Types.kt
+++ b/compiler/fir/tree/tree-generator/src/org/jetbrains/kotlin/fir/tree/generator/Types.kt
@@ -148,6 +148,7 @@
 val firDefaultVisitorType = generatedType("visitors", "FirDefaultVisitor")
 val firDefaultVisitorVoidType = generatedType("visitors", "FirDefaultVisitorVoid")
 val firTransformerType = generatedType("visitors", "FirTransformer")
+val firCompositeVisitorType = generatedType("visitors", "FirCompositeVisitor")
 
 val resolveStateAccessAnnotation = type("fir.declarations", "ResolveStateAccess", kind = TypeKind.Class)
 val unresolvedExpressionTypeAccessAnnotation = type("fir.expressions", "UnresolvedExpressionTypeAccess", kind = TypeKind.Class)
diff --git a/compiler/fir/tree/tree-generator/src/org/jetbrains/kotlin/fir/tree/generator/printer/CompositeVisitorPrinter.kt b/compiler/fir/tree/tree-generator/src/org/jetbrains/kotlin/fir/tree/generator/printer/CompositeVisitorPrinter.kt
new file mode 100644
index 0000000..44b23cb
--- /dev/null
+++ b/compiler/fir/tree/tree-generator/src/org/jetbrains/kotlin/fir/tree/generator/printer/CompositeVisitorPrinter.kt
@@ -0,0 +1,53 @@
+/*
+ * Copyright 2010-2025 JetBrains s.r.o. and Kotlin Programming Language contributors.
+ * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
+ */
+
+package org.jetbrains.kotlin.fir.tree.generator.printer
+
+import org.jetbrains.kotlin.fir.tree.generator.firVisitorType
+import org.jetbrains.kotlin.fir.tree.generator.model.Element
+import org.jetbrains.kotlin.fir.tree.generator.model.Field
+import org.jetbrains.kotlin.generators.tree.*
+import org.jetbrains.kotlin.generators.tree.printer.FunctionParameter
+import org.jetbrains.kotlin.generators.tree.printer.ImportCollectingPrinter
+import org.jetbrains.kotlin.generators.tree.printer.PrimaryConstructorParameter
+import org.jetbrains.kotlin.generators.tree.printer.VariableKind
+import org.jetbrains.kotlin.generators.util.printBlock
+import org.jetbrains.kotlin.types.Variance
+
+internal class CompositeVisitorPrinter(
+    printer: ImportCollectingPrinter,
+    override val visitorType: ClassRef<*>,
+) : AbstractVisitorPrinter<Element, Field>(printer) {
+
+    override val implementationKind: ImplementationKind
+        get() = ImplementationKind.FinalClass
+
+    override val visitorTypeParameters: List<TypeVariable>
+        get() = listOf(dataTypeVariable)
+
+    override val visitorSuperTypes: List<ClassRef<PositionTypeParameterRef>> =
+        listOfNotNull(firVisitorType.withArgs(StandardTypes.unit, dataTypeVariable))
+
+    override val constructorParameters: List<PrimaryConstructorParameter> =
+        listOf(PrimaryConstructorParameter(FunctionParameter("visitors", StandardTypes.array.withArgs(TypeRefWithVariance(Variance.OUT_VARIANCE, firVisitorType.withArgs(StandardTypes.unit, dataTypeVariable)))), VariableKind.VAL))
+
+    override val visitorDataType: TypeRef
+        get() = dataTypeVariable
+
+    override val allowTypeParametersInVisitorMethods: Boolean
+        get() = true
+
+    override fun visitMethodReturnType(element: Element) = StandardTypes.unit
+
+    override fun printMethodsForElement(element: Element) {
+        printer.run {
+            printMethodDeclarationForElement(element, modality = null, override = true)
+            printBlock {
+                println("visitors.forEach { it.${element.visitFunctionName}(${element.visitorParameterName}, data) }")
+            }
+        }
+    }
+
+}