blob: 5e06cf6875a4a0e23b21e7ee04a059ef2b6946e4 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2019 Marco Stornelli
*
* This program and the accompanying materials
* are made available under the terms of the Eclipse Public License 2.0
* which accompanies this distribution, and is available at
* https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
*******************************************************************************/
package org.eclipse.cdt.codan.internal.checkers;
import org.eclipse.cdt.codan.checkers.CodanCheckersActivator;
import org.eclipse.cdt.codan.core.cxx.model.AbstractIndexAstChecker;
import org.eclipse.cdt.core.dom.ast.ASTVisitor;
import org.eclipse.cdt.core.dom.ast.DOMException;
import org.eclipse.cdt.core.dom.ast.EScopeKind;
import org.eclipse.cdt.core.dom.ast.IASTDeclSpecifier;
import org.eclipse.cdt.core.dom.ast.IASTDeclaration;
import org.eclipse.cdt.core.dom.ast.IASTDeclarationStatement;
import org.eclipse.cdt.core.dom.ast.IASTDeclarator;
import org.eclipse.cdt.core.dom.ast.IASTForStatement;
import org.eclipse.cdt.core.dom.ast.IASTIfStatement;
import org.eclipse.cdt.core.dom.ast.IASTNode;
import org.eclipse.cdt.core.dom.ast.IASTSimpleDeclaration;
import org.eclipse.cdt.core.dom.ast.IASTSwitchStatement;
import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit;
import org.eclipse.cdt.core.dom.ast.IBinding;
import org.eclipse.cdt.core.dom.ast.IScope;
import org.eclipse.cdt.core.dom.ast.IVariable;
public class VariableInitializationChecker extends AbstractIndexAstChecker {
public static final String STATIC_VAR_ID = "org.eclipse.cdt.codan.internal.checkers.StaticVariableInHeaderProblem"; //$NON-NLS-1$
public static final String VAR_MULTI_DEC_ID = "org.eclipse.cdt.codan.internal.checkers.MultipleDeclarationsProblem"; //$NON-NLS-1$
@Override
public void processAst(IASTTranslationUnit ast) {
ast.accept(new ASTVisitor() {
{
shouldVisitDeclarations = true;
}
@Override
public int visit(IASTDeclaration declaration) {
if (declaration instanceof IASTSimpleDeclaration) {
IASTSimpleDeclaration simple = (IASTSimpleDeclaration) declaration;
IASTDeclarator decls[] = ((IASTSimpleDeclaration) declaration).getDeclarators();
if (simple.getDeclSpecifier().getStorageClass() == IASTDeclSpecifier.sc_static
&& declaration.getTranslationUnit().isHeaderUnit()) {
for (IASTDeclarator d : decls) {
IBinding binding = d.getName().resolveBinding();
if (binding != null && binding instanceof IVariable) {
try {
IScope scope = binding.getScope();
if (scope == null)
return PROCESS_CONTINUE;
if (scope.getKind() == EScopeKind.eGlobal
|| scope.getKind() == EScopeKind.eNamespace)
reportProblem(STATIC_VAR_ID, declaration, d.getName());
} catch (DOMException e) {
CodanCheckersActivator.log(e);
}
}
}
}
if (declaration.getParent() instanceof IASTDeclarationStatement) {
IASTNode node = declaration.getParent().getParent();
if (node instanceof IASTForStatement || node instanceof IASTIfStatement
|| node instanceof IASTSwitchStatement) {
//we allow multiple declarations for if/switch initializers and for statements
return PROCESS_CONTINUE;
}
}
if (decls.length == 0)
return PROCESS_CONTINUE;
if (decls.length != 1)
reportProblem(VAR_MULTI_DEC_ID, declaration);
}
return PROCESS_CONTINUE;
}
});
}
}