blob: e2ca07786e591a5d711fdd0e0548ffc3b1ce28e6 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2007, 2009 Wind River Systems, Inc. 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
*
* Contributors:
* Markus Schorn - initial API and implementation
*******************************************************************************/
package org.eclipse.cdt.internal.core.dom.parser.c;
import org.eclipse.cdt.core.dom.ast.IASTEqualsInitializer;
import org.eclipse.cdt.core.dom.ast.IASTExpression;
import org.eclipse.cdt.core.dom.ast.IASTFunctionCallExpression;
import org.eclipse.cdt.core.dom.ast.IASTName;
import org.eclipse.cdt.core.dom.ast.IASTNode;
import org.eclipse.cdt.core.dom.ast.IPointerType;
import org.eclipse.cdt.core.dom.ast.IQualifierType;
import org.eclipse.cdt.core.dom.ast.IType;
import org.eclipse.cdt.core.dom.ast.c.ICASTFieldDesignator;
import org.eclipse.cdt.core.dom.ast.c.ICASTTypeIdInitializerExpression;
import org.eclipse.cdt.internal.core.dom.parser.VariableReadWriteFlags;
/**
* Helper class to determine whether a variable is accessed for reading and/or writing.
* The algorithm works starting from the variable and looking upwards what's being done
* with the variable.
*/
public final class CVariableReadWriteFlags extends VariableReadWriteFlags {
private static CVariableReadWriteFlags INSTANCE= new CVariableReadWriteFlags();
public static int getReadWriteFlags(IASTName variable) {
return INSTANCE.rwAnyNode(variable, 0);
}
@Override
protected int rwAnyNode(IASTNode node, int indirection) {
final IASTNode parent= node.getParent();
if (parent instanceof ICASTFieldDesignator) {
return WRITE; // node is initialized via designated initializer
}
return super.rwAnyNode(node, indirection);
}
@Override
protected int rwInExpression(IASTExpression expr, IASTNode node, int indirection) {
if (expr instanceof ICASTTypeIdInitializerExpression) {
return 0;
}
return super.rwInExpression(expr, node, indirection);
}
@Override
protected int rwInEqualsInitializer(IASTEqualsInitializer parent, int indirection) {
if (indirection == 0) {
return READ;
}
return super.rwInEqualsInitializer(parent, indirection);
}
@Override
protected int rwArgumentForFunctionCall(IASTFunctionCallExpression funcCall, IASTNode argument, int indirection) {
if (indirection == 0) {
return READ;
}
return super.rwArgumentForFunctionCall(funcCall, argument, indirection);
}
@Override
protected int rwAssignmentToType(IType type, int indirection) {
if (indirection == 0) {
return READ;
}
while (indirection > 0 && (type instanceof IPointerType)) {
type= ((IPointerType) type).getType();
indirection--;
}
if (indirection == 0) {
if (type instanceof IQualifierType) {
return ((IQualifierType) type).isConst() ? READ : READ | WRITE;
} else if (type instanceof IPointerType) {
return ((IPointerType) type).isConst() ? READ : READ | WRITE;
}
}
return READ | WRITE; // fallback
}
}