/******************************************************************************* * Copyright (c) 2005, 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: * Doug Schaefer (QNX) - Initial API and implementation * Markus Schorn (Wind River Systems) * IBM Corporation *******************************************************************************/ package org.eclipse.cdt.internal.core.pdom.dom.cpp; import org.eclipse.cdt.core.CCorePlugin; import org.eclipse.cdt.core.dom.ast.IASTName; import org.eclipse.cdt.core.dom.ast.IBinding; import org.eclipse.cdt.core.dom.ast.IType; import org.eclipse.cdt.core.dom.ast.IValue; import org.eclipse.cdt.core.dom.ast.IVariable; import org.eclipse.cdt.core.dom.ast.cpp.ICPPVariable; import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPVariableReadWriteFlags; import org.eclipse.cdt.internal.core.index.IIndexCPPBindingConstants; import org.eclipse.cdt.internal.core.pdom.db.Database; import org.eclipse.cdt.internal.core.pdom.dom.PDOMLinkage; import org.eclipse.cdt.internal.core.pdom.dom.PDOMName; import org.eclipse.cdt.internal.core.pdom.dom.PDOMNode; import org.eclipse.cdt.internal.core.pdom.dom.c.PDOMCAnnotation; import org.eclipse.core.runtime.CoreException; /** * Binding for a c++ variable in the index, serves as a base class for fields. */ class PDOMCPPVariable extends PDOMCPPBinding implements ICPPVariable { private static final int TYPE_OFFSET = PDOMCPPBinding.RECORD_SIZE; private static final int VALUE_OFFSET = TYPE_OFFSET + Database.TYPE_SIZE; protected static final int ANNOTATIONS = VALUE_OFFSET + Database.VALUE_SIZE; // byte @SuppressWarnings("hiding") protected static final int RECORD_SIZE = ANNOTATIONS + 1; public PDOMCPPVariable(PDOMLinkage linkage, PDOMNode parent, IVariable variable) throws CoreException { super(linkage, parent, variable.getNameCharArray()); // Find the type record Database db = getDB(); setType(parent.getLinkage(), variable.getType()); db.putByte(record + ANNOTATIONS, encodeFlags(variable)); setValue(db, variable); } private void setValue(Database db, IVariable variable) throws CoreException { IValue val= variable.getInitialValue(); getLinkage().storeValue(record + VALUE_OFFSET, val); } @Override public void update(final PDOMLinkage linkage, IBinding newBinding) throws CoreException { if (newBinding instanceof IVariable) { final Database db = getDB(); IVariable var= (IVariable) newBinding; IType newType= var.getType(); setType(linkage, newType); setValue(db, var); db.putByte(record + ANNOTATIONS, encodeFlags(var)); } } private void setType(final PDOMLinkage linkage, IType newType) throws CoreException { linkage.storeType(record+TYPE_OFFSET, newType); } protected byte encodeFlags(IVariable variable) { return PDOMCPPAnnotation.encodeAnnotation(variable); } public PDOMCPPVariable(PDOMLinkage linkage, long record) { super(linkage, record); } @Override protected int getRecordSize() { return RECORD_SIZE; } @Override public int getNodeType() { return IIndexCPPBindingConstants.CPPVARIABLE; } public boolean isMutable() { // ISO/IEC 14882:2003 7.1.1.8 return false; } public IType getType() { try { return getLinkage().loadType(record + TYPE_OFFSET); } catch (CoreException e) { CCorePlugin.log(e); return null; } } public IValue getInitialValue() { try { return getLinkage().loadValue(record + VALUE_OFFSET); } catch (CoreException e) { CCorePlugin.log(e); return null; } } public boolean isAuto() { return getBit(getByte(record + ANNOTATIONS), PDOMCAnnotation.AUTO_OFFSET); } public boolean isExtern() { return getBit(getByte(record + ANNOTATIONS), PDOMCAnnotation.EXTERN_OFFSET); } public boolean isExternC() { return getBit(getByte(record + ANNOTATIONS), PDOMCPPAnnotation.EXTERN_C_OFFSET); } public boolean isRegister() { return getBit(getByte(record + ANNOTATIONS), PDOMCAnnotation.REGISTER_OFFSET); } public boolean isStatic() { return getBit(getByte(record + ANNOTATIONS), PDOMCAnnotation.STATIC_OFFSET); } @Override public int getAdditionalNameFlags(int standardFlags, IASTName name) { if ((standardFlags & PDOMName.IS_REFERENCE) == PDOMName.IS_REFERENCE) { return CPPVariableReadWriteFlags.getReadWriteFlags(name); } return 0; } }