diff --git a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/ide/AcceptAllFilter.java b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/ide/AcceptAllFilter.java
new file mode 100644
index 000000000000..ed68a4dad7e5
--- /dev/null
+++ b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/ide/AcceptAllFilter.java
@@ -0,0 +1,41 @@
+/*
+ * Copyright (c) 2025, 2025, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package jdk.graal.compiler.ide;
+
+/**
+ * An implementation of {@link ClassFilter} that accepts all classes.
+ *
+ * This filter always returns {@code true} for any given class name, effectively allowing reports on
+ * all classes.
+ */
+public enum AcceptAllFilter implements ClassFilter {
+ INSTANCE;
+
+ @Override
+ public boolean shouldBeReported(String className) {
+ return true;
+ }
+
+}
diff --git a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/ide/ClassFilter.java b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/ide/ClassFilter.java
new file mode 100644
index 000000000000..20f7547265b3
--- /dev/null
+++ b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/ide/ClassFilter.java
@@ -0,0 +1,65 @@
+/*
+ * Copyright (c) 2025, 2025, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package jdk.graal.compiler.ide;
+
+import java.util.ArrayList;
+
+/**
+ * The ClassFilter interface provides a way to filter classes based on their names. Implementations
+ * of this interface can be used to determine whether a class should be reported or not.
+ *
+ * @see IDEReport
+ */
+public sealed interface ClassFilter permits PrefixFilter, CompositeFilter, AcceptAllFilter {
+
+ /**
+ * Checks whether a class with the given name should be included in the reports.
+ *
+ * @param className the name of the class to check
+ * @return true if the class should be included in reports, false otherwise
+ */
+ boolean shouldBeReported(String className);
+
+ /**
+ * Creates a ClassFilter instance based on a filter description. The filter description is a
+ * comma-separated list of prefixes.
+ *
+ * @param filterDescr the filter description
+ * @return a ClassFilter instance that matches the given description
+ */
+ static ClassFilter parseFilterDescr(String filterDescr) {
+ var individualFilterDescr = filterDescr.split(",");
+ var filters = new ArrayList(individualFilterDescr.length);
+ for (var descr : individualFilterDescr) {
+ filters.add(new PrefixFilter(descr));
+ }
+ return switch (filters.size()) {
+ case 0 -> AcceptAllFilter.INSTANCE;
+ case 1 -> filters.getFirst();
+ default -> new CompositeFilter(filters);
+ };
+ }
+
+}
diff --git a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/ide/CompositeFilter.java b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/ide/CompositeFilter.java
new file mode 100644
index 000000000000..5ee46eb232cd
--- /dev/null
+++ b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/ide/CompositeFilter.java
@@ -0,0 +1,43 @@
+/*
+ * Copyright (c) 2025, 2025, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package jdk.graal.compiler.ide;
+
+import java.util.List;
+
+/**
+ * A composite {@link ClassFilter} that delegates the filtering decision to a list of underlying
+ * ClassFilters. A class is considered to be reported if at least one of the underlying filters
+ * returns true.
+ *
+ * @param filters the list of ClassFilters to be used for filtering
+ */
+public record CompositeFilter(List filters) implements ClassFilter {
+
+ @Override
+ public boolean shouldBeReported(String className) {
+ return filters.stream().anyMatch(f -> f.shouldBeReported(className));
+ }
+
+}
diff --git a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/ide/IDEReport.java b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/ide/IDEReport.java
new file mode 100644
index 000000000000..994e14750e01
--- /dev/null
+++ b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/ide/IDEReport.java
@@ -0,0 +1,385 @@
+/*
+ * Copyright (c) 2025, 2025, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package jdk.graal.compiler.ide;
+
+import java.io.FileWriter;
+import java.io.IOException;
+import java.io.PrintWriter;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.time.LocalDateTime;
+import java.time.format.DateTimeFormatter;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.ConcurrentLinkedQueue;
+import java.util.function.Consumer;
+import java.util.stream.Collectors;
+
+import org.graalvm.collections.EconomicMap;
+
+import jdk.graal.compiler.core.common.GraalOptions;
+import jdk.graal.compiler.graph.NodeSourcePosition;
+import jdk.graal.compiler.graph.SourceLanguagePosition;
+import jdk.graal.compiler.options.Option;
+import jdk.graal.compiler.options.OptionKey;
+import jdk.graal.compiler.util.json.JsonFormatter;
+import jdk.vm.ci.meta.ResolvedJavaMethod;
+import jdk.vm.ci.meta.ResolvedJavaType;
+
+/**
+ * The IDEReport class is responsible for generating reports for IDE plugins. It provides methods to
+ * save various types of reports, such as line reports, unreachable range reports, class reports,
+ * field reports, and method reports.
+ *
+ * The reports are stored in a JSON file, which can be used by an IDE plugin to display the
+ * information to the user.
+ */
+public final class IDEReport {
+
+ // TODO rename filename into filepath (also in IDE plugin)
+
+ private static final String REPORT_KIND_K = "kind";
+ private static final String FILENAME_K = "filename";
+ private static final String LINE_K = "line";
+ private static final String START_LINE_K = "start-line";
+ private static final String END_LINE_K = "end-line";
+ private static final String MSG_K = "msg";
+ private static final String INLINE_CTX_K = "inlinectx";
+ private static final String CLASS_K = "class";
+ private static final String FIELD_K = "field";
+ private static final String MTH_NAME_K = "mthname";
+ private static final String MTH_SIG_K = "mthsig";
+
+ private static final String REPORT_KIND_LINE = "LINE";
+ private static final String REPORT_KIND_UNREACHABLE_RANGE = "UNREACHABLE";
+ private static final String REPORT_KIND_CLASS = "CLASS";
+ private static final String REPORT_KIND_CLASS_FIELD = "FIELD";
+ private static final String REPORT_KIND_METHOD = "METHOD";
+
+ private static final String REPORTS_LIST_TOPLEVEL_KEY = "reports";
+ private static final String USED_METHODS_TOPLEVEL_KEY = "used_methods";
+
+ public static final class Options {
+ private Options() {
+ }
+
+ @Option(help = "Print build report for the Native Image Intellij plugin.")//
+ public static final OptionKey IDEReport = new OptionKey<>(false) {
+ @Override
+ protected void onValueUpdate(EconomicMap, Object> values, Boolean oldValue, Boolean newValue) {
+ if (newValue) {
+ GraalOptions.TrackNodeSourcePosition.update(values, true);
+ }
+ }
+ };
+
+ @Option(help = "Print build report for the Native Image Intellij plugin for the specified set of files.")//
+ public static final OptionKey IDEReportFiltered = new OptionKey<>("") {
+ @Override
+ protected void onValueUpdate(EconomicMap, Object> values, String oldValue, String newValue) {
+ if (newValue != null) {
+ Options.IDEReport.update(values, true);
+ }
+ }
+ };
+
+ }
+
+ private static IDEReport instance = null;
+
+ private final ClassFilter filter;
+
+ private final ConcurrentLinkedQueue