| /******************************************************************************* |
| * 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 |
| } |
| } |