diff --git a/core/org.eclipse.cdt.core/plugin.properties b/core/org.eclipse.cdt.core/plugin.properties
index f06189e829e..9f72cc6d3a7 100755
--- a/core/org.eclipse.cdt.core/plugin.properties
+++ b/core/org.eclipse.cdt.core/plugin.properties
@@ -138,3 +138,5 @@ uncPathConverter.name = UNC Path Converter
ScannerInfoExtensionLanguageSettingsProvider.name=Contributed ScannerInfo Entries
PathEntryScannerInfoLanguageSettingsProvider.name=Contributed PathEntry Containers
ReferencedProjectsLanguageSettingsProvider.name=Exported Entries from Referenced Projects
+
+problemMarkerFilter.name=Problem Marker Filter
diff --git a/core/org.eclipse.cdt.core/plugin.xml b/core/org.eclipse.cdt.core/plugin.xml
index 3d6764c38ec..9bfaba5143d 100644
--- a/core/org.eclipse.cdt.core/plugin.xml
+++ b/core/org.eclipse.cdt.core/plugin.xml
@@ -675,6 +675,7 @@
+
diff --git a/core/org.eclipse.cdt.core/schema/ProblemMarkerFilter.exsd b/core/org.eclipse.cdt.core/schema/ProblemMarkerFilter.exsd
new file mode 100644
index 00000000000..3a575f9f9e7
--- /dev/null
+++ b/core/org.eclipse.cdt.core/schema/ProblemMarkerFilter.exsd
@@ -0,0 +1,135 @@
+
+
+
+
+
+
+
+
+ This extension point allows to filter out unneeded problem markers.
+ For example during building of Qt base project with QML files tool Qt Linguist
+ could report syntax errors in some qml file. These errors are presented as
+ "C/C++ Problems" in qml files because they match format CDT expects for errors.
+ If there is already installed plug-in that handles QML files it is a wise to ignore such
+ errors because they are already reported as "QML Problems" with more meaningful descriptions.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ a fully qualified identifier of the target extension point
+
+
+
+
+
+
+ an optional identifier of the extension instance
+
+
+
+
+
+
+ an optional name of the extension instance
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Implementation of Problem Marker Filter that allows to filter out unneded or duplicit problem markers.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 8.3
+
+
+
+
+
+
+
+
+ The following is an example of a qmakeEnvProvider contribution:
+<p>
+<pre>
+<extension
+ point="org.eclipse.cdt.core.ProblemMarkerFilter"
+ id="example"
+ name="Example QMake Env Provider Extension">
+ <problemMarkerFilter
+ class="com.example.internal.ProblemMarkerFilter">
+ <enablement>
+ <with variable="projectNatures">
+ <iterate operator="or">
+ <equals value="com.example.my-nature"/>
+ </iterate>
+ </with>
+ </enablement>
+ </problemMarkerFilter>
+</extension>
+</pre>
+</p>
+
+
+
+
+
+
+
+
+ The contributed class must implement <code>org.eclipse.cdt.core.IProblemMarkerFilter</code>.
+
+
+
+
+
+
+
+
+ Copyright (c) 2014 BlackBerry Limited and others.
+ All rights reserved. This program and the accompanying materials
+ are made available under the terms of the Eclipse Public License v1.0
+ which accompanies this distribution, and is available at
+ http://www.eclipse.org/legal/epl-v10.html
+
+
+
+
+
diff --git a/core/org.eclipse.cdt.core/src/org/eclipse/cdt/core/ErrorParserManager.java b/core/org.eclipse.cdt.core/src/org/eclipse/cdt/core/ErrorParserManager.java
index 735d8ce086a..12c4ab08e0d 100644
--- a/core/org.eclipse.cdt.core/src/org/eclipse/cdt/core/ErrorParserManager.java
+++ b/core/org.eclipse.cdt.core/src/org/eclipse/cdt/core/ErrorParserManager.java
@@ -30,6 +30,7 @@ import org.eclipse.cdt.core.language.settings.providers.IWorkingDirectoryTracker
import org.eclipse.cdt.core.resources.ACBuilder;
import org.eclipse.cdt.internal.core.Cygwin;
import org.eclipse.cdt.internal.core.IErrorMarkeredOutputStream;
+import org.eclipse.cdt.internal.core.ProblemMarkerFilterManager;
import org.eclipse.cdt.internal.core.resources.ResourceLookup;
import org.eclipse.cdt.internal.errorparsers.ErrorParserExtensionManager;
import org.eclipse.cdt.utils.EFSExtensionManager;
@@ -588,6 +589,8 @@ outer:
* @since 5.4
*/
public void addProblemMarker(ProblemMarkerInfo problemMarkerInfo){
+ if ( ! ProblemMarkerFilterManager.getInstance().acceptMarker(problemMarkerInfo) )
+ return;
fErrors.add(problemMarkerInfo);
fMarkerGenerator.addMarker(problemMarkerInfo);
if (problemMarkerInfo.severity == IMarkerGenerator.SEVERITY_ERROR_RESOURCE) {
diff --git a/core/org.eclipse.cdt.core/src/org/eclipse/cdt/core/IProblemMarkerFilter.java b/core/org.eclipse.cdt.core/src/org/eclipse/cdt/core/IProblemMarkerFilter.java
new file mode 100644
index 00000000000..9bdb22b8907
--- /dev/null
+++ b/core/org.eclipse.cdt.core/src/org/eclipse/cdt/core/IProblemMarkerFilter.java
@@ -0,0 +1,25 @@
+/*
+ * Copyright (c) 2014 BlackBerry Limited and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.eclipse.cdt.core;
+
+/**
+ * The purpose of IProblemMarkerFilter is to provide filtering function for problem markers.
+ * ProblemMarkerFilter extension point are required to implements this interface.
+ *
+ * @since 5.6
+ */
+public interface IProblemMarkerFilter {
+
+ /**
+ * Decide if a problem marker should be reported or ignored.
+ *
+ * @param markerInfo description of the problem marker that is going to be reported
+ * @return true if markers should be reported, false if should be ignored
+ */
+ boolean acceptMarker(ProblemMarkerInfo markerInfo);
+}
diff --git a/core/org.eclipse.cdt.core/src/org/eclipse/cdt/internal/core/ProblemMarkerFilterDesc.java b/core/org.eclipse.cdt.core/src/org/eclipse/cdt/internal/core/ProblemMarkerFilterDesc.java
new file mode 100644
index 00000000000..b794a21f5df
--- /dev/null
+++ b/core/org.eclipse.cdt.core/src/org/eclipse/cdt/internal/core/ProblemMarkerFilterDesc.java
@@ -0,0 +1,160 @@
+/*
+ * Copyright (c) 2014 BlackBerry Limited and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.eclipse.cdt.internal.core;
+
+import java.util.Arrays;
+
+import org.eclipse.cdt.core.CCorePlugin;
+import org.eclipse.cdt.core.IProblemMarkerFilter;
+import org.eclipse.cdt.core.ProblemMarkerInfo;
+import org.eclipse.core.expressions.EvaluationContext;
+import org.eclipse.core.expressions.EvaluationResult;
+import org.eclipse.core.expressions.Expression;
+import org.eclipse.core.expressions.ExpressionConverter;
+import org.eclipse.core.expressions.ExpressionTagNames;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IConfigurationElement;
+
+/**
+ * The purpose of ProblemMarkerFilterDesc is to manage information about
+ * one instance ProblemMarkerFilter extension point.
+ */
+class ProblemMarkerFilterDesc {
+
+ /**
+ * XML attribute for name of class that implements this extension point
+ */
+ private static final String ATTR_CLASS = "class"; //$NON-NLS-1$
+
+ /**
+ * Variable name for projectNatures for enablement expression
+ */
+ private static final String VAR_PROJECTNATURES = "projectNatures"; //$NON-NLS-1$
+
+ /**
+ * Configuration element for this extension point
+ */
+ private final IConfigurationElement element;
+
+ /**
+ * Expression that allows conditionally enable/disable extension point
+ */
+ private final Expression enablementExpression;
+
+ /**
+ * Status of this extension point.
+ * False = disabled because of expression error
+ * True = enabled because of missing enablementExpression
+ * null = evaluate the expression for particular project
+ */
+ private Boolean fStatus = null;
+
+ /**
+ * Unique id of this extension point
+ */
+ private String id;
+
+ /**
+ *
+ */
+ private IProblemMarkerFilter filter;
+
+ /**
+ * Filter that accept any marker.
+ *
+ */
+ private static final IProblemMarkerFilter NULL_FILTER = new IProblemMarkerFilter() {
+
+ @Override
+ public boolean acceptMarker(ProblemMarkerInfo markerInfo) {
+ return true;
+ }
+
+ };
+
+ /**
+ * Constructor
+ *
+ * @param element configuration element with optional enablementExpression
+ */
+ ProblemMarkerFilterDesc(IConfigurationElement element) {
+ this.element = element;
+
+ Expression expr = null;
+ IConfigurationElement[] children = element.getChildren(ExpressionTagNames.ENABLEMENT);
+ switch (children.length) {
+ case 0:
+ fStatus = Boolean.TRUE;
+ break;
+ case 1:
+ try {
+ ExpressionConverter parser = ExpressionConverter.getDefault();
+ expr = parser.perform(children[0]);
+ } catch (CoreException e) {
+ CCorePlugin.log("Error in enablement expression of " + id, e); //$NON-NLS-1$
+ fStatus = Boolean.FALSE;
+ }
+ break;
+ default:
+ CCorePlugin.log("Too many enablement expressions for " + id); //$NON-NLS-1$
+ fStatus = Boolean.FALSE;
+ break;
+ }
+ enablementExpression = expr;
+ }
+
+ /**
+ * Evaluate enablement expression
+ *
+ * @param project project for which we had to evaluate the expression
+ * @return value of enablement expression
+ */
+ public boolean matches(IProject project) {
+ // If the enablement expression is missing or structurally invalid, then return immediately
+ if (fStatus != null)
+ return fStatus.booleanValue();
+
+ if (enablementExpression != null)
+ try {
+ EvaluationContext evalContext = new EvaluationContext(null, project);
+ String[] natures = project.getDescription().getNatureIds();
+ evalContext.addVariable(VAR_PROJECTNATURES, Arrays.asList(natures));
+ return enablementExpression.evaluate(evalContext) == EvaluationResult.TRUE;
+ } catch (CoreException e) {
+ CCorePlugin.log("Error while evaluating enablement expression for " + id, e); //$NON-NLS-1$
+ }
+
+ return false;
+ }
+
+ /**
+ * Return filter interface
+ * @return Filter interface or NULL_FILER if filter could not be created
+ */
+ IProblemMarkerFilter getFilter() {
+ if (filter == null)
+ synchronized (this) {
+ if (filter == null) {
+ try {
+ filter = (IProblemMarkerFilter) element.createExecutableExtension(ATTR_CLASS);
+ } catch (CoreException e) {
+ String id = element.getDeclaringExtension().getNamespaceIdentifier() + '.'
+ + element.getDeclaringExtension().getSimpleIdentifier();
+ CCorePlugin.log("Error in class attribute of " + id, e); //$NON-NLS-1$
+
+ // mark the filter with an empty implementation to prevent future load attempts
+ filter = NULL_FILTER;
+ }
+ }
+ }
+
+ return filter;
+ }
+
+}
diff --git a/core/org.eclipse.cdt.core/src/org/eclipse/cdt/internal/core/ProblemMarkerFilterManager.java b/core/org.eclipse.cdt.core/src/org/eclipse/cdt/internal/core/ProblemMarkerFilterManager.java
new file mode 100644
index 00000000000..5409cd262a8
--- /dev/null
+++ b/core/org.eclipse.cdt.core/src/org/eclipse/cdt/internal/core/ProblemMarkerFilterManager.java
@@ -0,0 +1,124 @@
+/*
+ * Copyright (c) 2014 BlackBerry Limited and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.eclipse.cdt.internal.core;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.WeakHashMap;
+
+import org.eclipse.cdt.core.CCorePlugin;
+import org.eclipse.cdt.core.ErrorParserManager;
+import org.eclipse.cdt.core.IProblemMarkerFilter;
+import org.eclipse.cdt.core.ProblemMarkerInfo;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.runtime.IConfigurationElement;
+import org.eclipse.core.runtime.IExtensionRegistry;
+import org.eclipse.core.runtime.Platform;
+
+/**
+ * The purpose of ProblemMarkerFilterManager is to manage ProblemMarkerFilter extension points.
+ * {@link ErrorParserManager} use this manager to filter out unnecessary problem markers
+ *
+ * @noextend This class is not intended to be subclassed by clients.
+ */
+public class ProblemMarkerFilterManager {
+
+ /**
+ * Name of ProblemMarkerFilter extension point
+ */
+ private final static String EXTENSION_POINT = "ProblemMarkerFilter"; //$NON-NLS-1$
+
+ /**
+ * Singleton instance of ProblemMarkerFilterManager
+ */
+ private final static ProblemMarkerFilterManager INSTANCE = new ProblemMarkerFilterManager();
+
+ /**
+ * List of all executable extension registered in Extension Registry
+ */
+ private final List filters = new ArrayList();
+
+ /**
+ * Cache of active filters for known projects.
+ * This cache allow to skip evaluation of enablementExpression for every marker.
+ */
+ private final Map> filtersCache = new WeakHashMap>();
+
+ /**
+ * Return singleton instance of ProblemMarkerFilterManager
+ *
+ * @return singleton instance of ProblemMarkerFilterManager
+ */
+ public static ProblemMarkerFilterManager getInstance() {
+ return INSTANCE;
+ }
+
+ /**
+ * Constructor.
+ *
+ * Creates instances of executable extension for ProblemMarkerFilter extension point
+ *
+ */
+ private ProblemMarkerFilterManager() {
+ IExtensionRegistry reg = Platform.getExtensionRegistry();
+ IConfigurationElement[] extensions = reg
+ .getConfigurationElementsFor(CCorePlugin.PLUGIN_ID, EXTENSION_POINT);
+ for (int i = 0; i < extensions.length; i++) {
+ IConfigurationElement element = extensions[i];
+ ProblemMarkerFilterDesc filterDesc = new ProblemMarkerFilterDesc(element);
+ filters.add(filterDesc);
+ }
+ }
+
+ /**
+ * Called by {@link ErrorParserManager#addProblemMarker(ProblemMarkerInfo)} to filter out unnecessary problem markers
+ *
+ * Problem marker is ignored if any plug-in that implements ProblemMarkerFilter extension point rejects it.
+ *
+ * @see IProblemMarkerFilter#acceptMarker(ProblemMarkerInfo)
+ *
+ * @param markerInfo description of the problem marker that is going to be added
+ * @return true if markers should be reported, false if should be ignored
+ */
+ public boolean acceptMarker(ProblemMarkerInfo markerInfo) {
+ IProject project = markerInfo.file.getProject();
+ if (project == null || !project.isOpen())
+ return true;
+ List enabledFilters = findEnabledFilters(project);
+ for (ProblemMarkerFilterDesc filterDesc: enabledFilters) {
+ if ( ! filterDesc.getFilter().acceptMarker(markerInfo) ) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ /**
+ * Try to find enabled filter for project and cache results
+ * @param project project for which we want know enabled filters
+ * @return list of enabled filters
+ */
+ private List findEnabledFilters(IProject project) {
+ synchronized (filtersCache) {
+ List result = filtersCache.get(project);
+ if (result == null) {
+ result = new ArrayList();
+ for (ProblemMarkerFilterDesc filterDesc: filters) {
+ if ( filterDesc.matches(project) ) {
+ result.add(filterDesc);
+ }
+ }
+ filtersCache.put(project, result);
+ }
+ return result;
+ }
+ }
+
+}