/******************************************************************************* * Copyright (c) 2006, 2010 QNX Software Systems 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: * QNX - Initial API and implementation * IBM Corporation * Andrew Ferguson (Symbian) * Markus Schorn (Wind River Systems) *******************************************************************************/ package org.eclipse.cdt.internal.core.pdom.dom.c; import org.eclipse.cdt.core.CCorePlugin; import org.eclipse.cdt.core.dom.ast.IBinding; import org.eclipse.cdt.core.dom.ast.IFunction; import org.eclipse.cdt.core.dom.ast.IFunctionType; import org.eclipse.cdt.core.dom.ast.IParameter; import org.eclipse.cdt.core.dom.ast.IScope; import org.eclipse.cdt.core.dom.ast.ISemanticProblem; import org.eclipse.cdt.core.dom.ast.IType; import org.eclipse.cdt.internal.core.dom.parser.ProblemFunctionType; import org.eclipse.cdt.internal.core.index.IIndexCBindingConstants; import org.eclipse.cdt.internal.core.pdom.db.Database; import org.eclipse.cdt.internal.core.pdom.dom.PDOMBinding; import org.eclipse.cdt.internal.core.pdom.dom.PDOMLinkage; import org.eclipse.cdt.internal.core.pdom.dom.PDOMNode; import org.eclipse.core.runtime.CoreException; /** * @author Doug Schaefer * */ class PDOMCFunction extends PDOMBinding implements IFunction { /** * Offset of total number of function parameters (relative to the * beginning of the record). */ public static final int NUM_PARAMS = PDOMBinding.RECORD_SIZE; /** * Offset of total number of function parameters (relative to the * beginning of the record). */ public static final int FIRST_PARAM = NUM_PARAMS + 4; /** * Offset for the type of this function (relative to * the beginning of the record). */ private static final int FUNCTION_TYPE = FIRST_PARAM + Database.PTR_SIZE; /** * Offset of annotation information (relative to the beginning of the * record). */ private static final int ANNOTATIONS = FUNCTION_TYPE + Database.TYPE_SIZE; // byte /** * The size in bytes of a PDOMCPPFunction record in the database. */ @SuppressWarnings("hiding") public static final int RECORD_SIZE = ANNOTATIONS + 1; public PDOMCFunction(PDOMLinkage linkage, long record) { super(linkage, record); } public PDOMCFunction(PDOMLinkage linkage, PDOMNode parent, IFunction function) throws CoreException { super(linkage, parent, function.getNameCharArray()); IFunctionType type; IParameter[] parameters; byte annotations; type = function.getType(); parameters = function.getParameters(); annotations = PDOMCAnnotation.encodeAnnotation(function); setType(getLinkage(), type); setParameters(parameters); getDB().putByte(record + ANNOTATIONS, annotations); } @Override public void update(final PDOMLinkage linkage, IBinding newBinding) throws CoreException { if (newBinding instanceof IFunction) { IFunction func= (IFunction) newBinding; IFunctionType newType; IParameter[] newParams; byte newAnnotation; newType= func.getType(); newParams = func.getParameters(); newAnnotation = PDOMCAnnotation.encodeAnnotation(func); setType(linkage, newType); PDOMCParameter oldParams= getFirstParameter(null); setParameters(newParams); if (oldParams != null) { oldParams.delete(linkage); } getDB().putByte(record + ANNOTATIONS, newAnnotation); } } private void setType(PDOMLinkage linkage, IFunctionType ft) throws CoreException { linkage.storeType(record+FUNCTION_TYPE, ft); } private void setParameters(IParameter[] params) throws CoreException { final PDOMLinkage linkage = getLinkage(); final Database db= getDB(); db.putInt(record + NUM_PARAMS, params.length); db.putRecPtr(record + FIRST_PARAM, 0); PDOMCParameter next= null; for (int i= params.length-1; i >= 0; --i) { next= new PDOMCParameter(linkage, this, params[i], next); } db.putRecPtr(record + FIRST_PARAM, next == null ? 0 : next.getRecord()); } public PDOMCParameter getFirstParameter(IType t) throws CoreException { long rec = getDB().getRecPtr(record + FIRST_PARAM); return rec != 0 ? new PDOMCParameter(getLinkage(), rec, t) : null; } @Override protected int getRecordSize() { return RECORD_SIZE; } @Override public int getNodeType() { return IIndexCBindingConstants.CFUNCTION; } public IFunctionType getType() { try { return (IFunctionType) getLinkage().loadType(record + FUNCTION_TYPE); } catch(CoreException ce) { CCorePlugin.log(ce); return new ProblemFunctionType(ISemanticProblem.TYPE_NOT_PERSISTED); } } public boolean isStatic() { return getBit(getByte(record + ANNOTATIONS), PDOMCAnnotation.STATIC_OFFSET); } public boolean isExtern() { return getBit(getByte(record + ANNOTATIONS), PDOMCAnnotation.EXTERN_OFFSET); } public IParameter[] getParameters() { try { PDOMLinkage linkage= getLinkage(); Database db= getDB(); IFunctionType ft = getType(); IType[] ptypes= ft == null ? IType.EMPTY_TYPE_ARRAY : ft.getParameterTypes(); int n = db.getInt(record + NUM_PARAMS); IParameter[] result = new IParameter[n]; long next = db.getRecPtr(record + FIRST_PARAM); for (int i = 0; i < n && next != 0; i++) { IType type= i<ptypes.length ? ptypes[i] : null; final PDOMCParameter par = new PDOMCParameter(linkage, next, type); next= par.getNextPtr(); result[i]= par; } return result; } catch (CoreException e) { CCorePlugin.log(e); return IParameter.EMPTY_PARAMETER_ARRAY; } } public boolean isAuto() { // ISO/IEC 9899:TC1 6.9.1.4 return false; } public boolean isRegister() { // ISO/IEC 9899:TC1 6.9.1.4 return false; } public boolean isInline() { return getBit(getByte(record + ANNOTATIONS), PDOMCAnnotation.INLINE_OFFSET); } public boolean takesVarArgs() { return getBit(getByte(record + ANNOTATIONS), PDOMCAnnotation.VARARGS_OFFSET); } public IScope getFunctionScope() { return null; } }