mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-07-24 09:25:31 +02:00
Refactored common function to utility class
This commit is contained in:
parent
4f2aa8c7db
commit
94cb067beb
2 changed files with 71 additions and 22 deletions
|
@ -11,37 +11,41 @@
|
|||
package org.eclipse.cdt.codan.internal.checkers;
|
||||
|
||||
import org.eclipse.cdt.codan.checkers.CodanCheckersActivator;
|
||||
import org.eclipse.cdt.codan.core.cxx.CxxAstUtils;
|
||||
import org.eclipse.cdt.codan.core.cxx.model.AbstractIndexAstChecker;
|
||||
import org.eclipse.cdt.core.dom.ast.ASTVisitor;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTDeclSpecifier;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTDeclaration;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTDeclarator;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTName;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTNamedTypeSpecifier;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTPointer;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTPointerOperator;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTSimpleDeclaration;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTStatement;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit;
|
||||
import org.eclipse.cdt.core.dom.ast.IBasicType;
|
||||
import org.eclipse.cdt.core.dom.ast.IBinding;
|
||||
import org.eclipse.cdt.core.dom.ast.IPointerType;
|
||||
import org.eclipse.cdt.core.dom.ast.IType;
|
||||
import org.eclipse.cdt.core.dom.ast.ITypedef;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTCatchHandler;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTNamedTypeSpecifier;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTReferenceOperator;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTTryBlockStatement;
|
||||
|
||||
/**
|
||||
* Catching by reference is recommended by C++ experts, for example Herb Sutter/Andrei Alexandresscu "C++ Coding Standards", Rule 73 "Throw by value, catch by reference".
|
||||
* Catching by reference is recommended by C++ experts, for example Herb
|
||||
* Sutter/Andrei Alexandresscu "C++ Coding Standards", Rule 73
|
||||
* "Throw by value, catch by reference".
|
||||
* For one thing, this avoids copying and potentially slicing the exception.
|
||||
*
|
||||
*
|
||||
*/
|
||||
public class CatchByReference extends AbstractIndexAstChecker {
|
||||
public static final String ER_ID = "org.eclipse.cdt.codan.internal.checkers.CatchByReference";
|
||||
public static final String ER_ID = "org.eclipse.cdt.codan.internal.checkers.CatchByReference"; //$NON-NLS-1$
|
||||
|
||||
public void processAst(IASTTranslationUnit ast) {
|
||||
// traverse the ast using the visitor pattern.
|
||||
ast.accept(new OnCatch());
|
||||
}
|
||||
|
||||
class OnCatch extends ASTVisitor {
|
||||
OnCatch() {
|
||||
shouldVisitStatements = true;
|
||||
|
@ -51,26 +55,26 @@ public class CatchByReference extends AbstractIndexAstChecker {
|
|||
if (stmt instanceof ICPPASTTryBlockStatement) {
|
||||
try {
|
||||
ICPPASTTryBlockStatement tblock = (ICPPASTTryBlockStatement) stmt;
|
||||
ICPPASTCatchHandler[] catchHandlers = tblock.getCatchHandlers();
|
||||
next: for (int i = 0; i < catchHandlers.length; i++) {
|
||||
ICPPASTCatchHandler[] catchHandlers = tblock
|
||||
.getCatchHandlers();
|
||||
for (int i = 0; i < catchHandlers.length; i++) {
|
||||
ICPPASTCatchHandler catchHandler = catchHandlers[i];
|
||||
IASTDeclaration decl = catchHandler.getDeclaration();
|
||||
if (decl instanceof IASTSimpleDeclaration) {
|
||||
IASTSimpleDeclaration sdecl = (IASTSimpleDeclaration) decl;
|
||||
IASTDeclSpecifier spec = sdecl.getDeclSpecifier();
|
||||
if (!usesReference(catchHandler)) {
|
||||
if (spec instanceof ICPPASTNamedTypeSpecifier) {
|
||||
IBinding typeName = ((ICPPASTNamedTypeSpecifier) spec).getName().getBinding();
|
||||
// unwind typedef chain
|
||||
while (typeName instanceof ITypedef) {
|
||||
IType t = ((ITypedef) typeName).getType();
|
||||
if (t instanceof IBasicType)
|
||||
continue next;
|
||||
if (t instanceof IBinding)
|
||||
typeName = (IBinding) t;
|
||||
else
|
||||
break;
|
||||
}
|
||||
if (spec instanceof IASTNamedTypeSpecifier) {
|
||||
IASTName tname = ((IASTNamedTypeSpecifier) spec)
|
||||
.getName();
|
||||
IType typeName = (IType) tname
|
||||
.resolveBinding();
|
||||
typeName = CxxAstUtils.getInstance()
|
||||
.unwindTypedef(typeName);
|
||||
if (typeName instanceof IBasicType
|
||||
|| typeName instanceof IPointerType
|
||||
|| typeName == null)
|
||||
continue;
|
||||
reportProblem(ER_ID, decl);
|
||||
}
|
||||
}
|
||||
|
@ -86,16 +90,19 @@ public class CatchByReference extends AbstractIndexAstChecker {
|
|||
|
||||
/**
|
||||
* If it uses reference or ponter
|
||||
*
|
||||
* @param catchHandler
|
||||
* @return
|
||||
*/
|
||||
private boolean usesReference(ICPPASTCatchHandler catchHandler) {
|
||||
IASTDeclaration declaration = catchHandler.getDeclaration();
|
||||
if (declaration instanceof IASTSimpleDeclaration) {
|
||||
IASTDeclarator[] declarators = ((IASTSimpleDeclaration) declaration).getDeclarators();
|
||||
IASTDeclarator[] declarators = ((IASTSimpleDeclaration) declaration)
|
||||
.getDeclarators();
|
||||
for (int i = 0; i < declarators.length; i++) {
|
||||
IASTDeclarator d = declarators[i];
|
||||
IASTPointerOperator[] pointerOperators = d.getPointerOperators();
|
||||
IASTPointerOperator[] pointerOperators = d
|
||||
.getPointerOperators();
|
||||
for (int j = 0; j < pointerOperators.length; j++) {
|
||||
IASTPointerOperator po = pointerOperators[j];
|
||||
if (po instanceof ICPPASTReferenceOperator) {
|
||||
|
|
|
@ -0,0 +1,42 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2009,2010 Alena Laskavaia
|
||||
* 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
|
||||
*
|
||||
* Contributors:
|
||||
* Alena Laskavaia - initial API and implementation
|
||||
*******************************************************************************/
|
||||
package org.eclipse.cdt.codan.core.cxx;
|
||||
|
||||
import org.eclipse.cdt.core.dom.ast.IBinding;
|
||||
import org.eclipse.cdt.core.dom.ast.IType;
|
||||
import org.eclipse.cdt.core.dom.ast.ITypedef;
|
||||
|
||||
/**
|
||||
* Useful functions for doing code analysis on c/c++ AST
|
||||
*/
|
||||
public final class CxxAstUtils {
|
||||
private static CxxAstUtils instance;
|
||||
private CxxAstUtils(){
|
||||
// private constructor
|
||||
}
|
||||
public synchronized static CxxAstUtils getInstance(){
|
||||
if (instance==null) instance = new CxxAstUtils();
|
||||
return instance;
|
||||
}
|
||||
public IType unwindTypedef(IType type) {
|
||||
if (!(type instanceof IBinding)) return type;
|
||||
IBinding typeName = (IBinding) type;
|
||||
// unwind typedef chain
|
||||
while (typeName instanceof ITypedef) {
|
||||
IType t = ((ITypedef) typeName).getType();
|
||||
if (t instanceof IBinding)
|
||||
typeName = (IBinding) t;
|
||||
else
|
||||
return t;
|
||||
}
|
||||
return (IType)typeName;
|
||||
}
|
||||
}
|
Loading…
Add table
Reference in a new issue