| /******************************************************************************* |
| * Copyright (c) 2005, 2011 IBM Corporation 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: |
| * John Camelon (IBM Rational Software) - Initial API and implementation |
| * Markus Schorn (Wind River Systems) |
| * Sergey Prigogin (Google) |
| *******************************************************************************/ |
| package org.eclipse.cdt.internal.core.dom.parser.c; |
| |
| import org.eclipse.cdt.core.dom.ast.ASTVisitor; |
| import org.eclipse.cdt.core.dom.ast.EScopeKind; |
| import org.eclipse.cdt.core.dom.ast.IASTDeclaration; |
| import org.eclipse.cdt.core.dom.ast.IASTFunctionDefinition; |
| import org.eclipse.cdt.core.dom.ast.IASTName; |
| import org.eclipse.cdt.core.dom.ast.IASTNode; |
| import org.eclipse.cdt.core.dom.ast.IASTParameterDeclaration; |
| import org.eclipse.cdt.core.dom.ast.IASTStandardFunctionDeclarator; |
| import org.eclipse.cdt.core.dom.ast.IScope; |
| import org.eclipse.cdt.core.parser.util.ArrayUtil; |
| import org.eclipse.cdt.internal.core.dom.parser.ASTQueries; |
| |
| /** |
| * A function declarator for plain C. |
| */ |
| public class CASTFunctionDeclarator extends CASTDeclarator implements IASTStandardFunctionDeclarator { |
| private IASTParameterDeclaration[] parameters; |
| private int parametersPos= -1; |
| private boolean varArgs; |
| private IScope scope; |
| |
| public CASTFunctionDeclarator() { |
| } |
| |
| public CASTFunctionDeclarator(IASTName name) { |
| super(name); |
| } |
| |
| @Override |
| public CASTFunctionDeclarator copy() { |
| return copy(CopyStyle.withoutLocations); |
| } |
| |
| @Override |
| public CASTFunctionDeclarator copy(CopyStyle style) { |
| CASTFunctionDeclarator copy = new CASTFunctionDeclarator(); |
| copy.varArgs = varArgs; |
| for (IASTParameterDeclaration param : getParameters()) { |
| copy.addParameterDeclaration(param == null ? null : param.copy(style)); |
| } |
| return copy(copy, style); |
| } |
| |
| @Override |
| public IASTParameterDeclaration[] getParameters() { |
| if (parameters == null) |
| return IASTParameterDeclaration.EMPTY_PARAMETERDECLARATION_ARRAY; |
| parameters = ArrayUtil.trimAt(IASTParameterDeclaration.class, parameters, parametersPos); |
| return parameters; |
| } |
| |
| @Override |
| public void addParameterDeclaration(IASTParameterDeclaration parameter) { |
| assertNotFrozen(); |
| if (parameter != null) { |
| parameter.setParent(this); |
| parameter.setPropertyInParent(FUNCTION_PARAMETER); |
| parameters = ArrayUtil.appendAt(IASTParameterDeclaration.class, parameters, ++parametersPos, parameter); |
| } |
| } |
| |
| @Override |
| public boolean takesVarArgs() { |
| return varArgs; |
| } |
| |
| @Override |
| public void setVarArgs(boolean value) { |
| assertNotFrozen(); |
| varArgs = value; |
| } |
| |
| @Override |
| protected boolean postAccept(ASTVisitor action) { |
| IASTParameterDeclaration[] params = getParameters(); |
| for (int i = 0; i < params.length; i++) { |
| if (!params[i].accept(action)) |
| return false; |
| } |
| return super.postAccept(action); |
| } |
| |
| @Override |
| public void replace(IASTNode child, IASTNode other) { |
| if (parameters != null) { |
| for (int i = 0; i < parameters.length; ++i) { |
| if (child == parameters[i]) { |
| other.setPropertyInParent(child.getPropertyInParent()); |
| other.setParent(child.getParent()); |
| parameters[i]= (IASTParameterDeclaration) other; |
| return; |
| } |
| } |
| } |
| super.replace(child, other); |
| } |
| |
| @Override |
| public IScope getFunctionScope() { |
| if (scope != null) |
| return scope; |
| |
| // introduce a scope for function declarations and definitions, only. |
| IASTNode node= getParent(); |
| while (!(node instanceof IASTDeclaration)) { |
| if (node==null) |
| return null; |
| node= node.getParent(); |
| } |
| if (node instanceof IASTParameterDeclaration) |
| return null; |
| |
| if (node instanceof IASTFunctionDefinition) { |
| scope= ((IASTFunctionDefinition) node).getScope(); |
| } else if (ASTQueries.findTypeRelevantDeclarator(this) == this) { |
| scope = new CScope(this, EScopeKind.eLocal); |
| } |
| return scope; |
| } |
| } |