/******************************************************************************* * Copyright (c) 2005, 2016 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.IASTNode; 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.ICPPFunction; import org.eclipse.cdt.core.dom.ast.cpp.ICPPVariable; import org.eclipse.cdt.internal.core.dom.parser.IntegralValue; 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.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; private static final int ANNOTATIONS = VALUE_OFFSET + Database.VALUE_SIZE; // byte @SuppressWarnings("hiding") protected static final int RECORD_SIZE = ANNOTATIONS + 1; public PDOMCPPVariable(PDOMCPPLinkage linkage, PDOMNode parent, ICPPVariable variable, boolean setTypeAndValue) throws CoreException { super(linkage, parent, variable.getNameCharArray()); // Find the type record Database db = getDB(); db.putByte(record + ANNOTATIONS, PDOMCPPAnnotations.encodeVariableAnnotations(variable)); if (setTypeAndValue) { setType(parent.getLinkage(), variable.getType()); linkage.new ConfigureVariable(variable, this); } } public void initData(IValue initialValue) { try { setValue(initialValue); } catch (CoreException e) { CCorePlugin.log(e); } } protected void setValue(IValue value) throws CoreException { getLinkage().storeValue(record + VALUE_OFFSET, value); } @Override public void update(final PDOMLinkage linkage, IBinding newBinding, IASTNode point) throws CoreException { if (newBinding instanceof IVariable) { final Database db = getDB(); ICPPVariable var= (ICPPVariable) newBinding; IType newType= var.getType(); setType(linkage, newType); setValue(var.getInitialValue()); db.putByte(record + ANNOTATIONS, PDOMCPPAnnotations.encodeVariableAnnotations(var)); } } protected void setType(final PDOMLinkage linkage, IType newType) throws CoreException { linkage.storeType(record + TYPE_OFFSET, newType); } public PDOMCPPVariable(PDOMLinkage linkage, long record) { super(linkage, record); } @Override protected int getRecordSize() { return RECORD_SIZE; } @Override public int getNodeType() { return IIndexCPPBindingConstants.CPPVARIABLE; } @Override public boolean isMutable() { // ISO/IEC 14882:2003 7.1.1.8 return false; } @Override public IType getType() { try { return getLinkage().loadType(record + TYPE_OFFSET); } catch (CoreException e) { CCorePlugin.log(e); return null; } } @Override public IValue getInitialValue() { try { return getLinkage().loadValue(record + VALUE_OFFSET); } catch (CoreException e) { CCorePlugin.log(e); return IntegralValue.UNKNOWN; } } @Override public boolean isAuto() { byte annotation = getAnnotations(); return !PDOMCPPAnnotations.isExtern(annotation) && !PDOMCPPAnnotations.isStatic(annotation) && getOwner() instanceof ICPPFunction; } @Override public boolean isExtern() { return PDOMCPPAnnotations.isExtern(getAnnotations()); } @Override public boolean isExternC() { return PDOMCPPAnnotations.isExternC(getAnnotations()); } @Override public boolean isRegister() { return false; // We don't care whether the parameter has register storage class specifier or not. } @Override public boolean isStatic() { return PDOMCPPAnnotations.isStatic(getAnnotations()); } @Override public boolean isConstexpr() { return PDOMCPPAnnotations.isConstexpr(getAnnotations()); } protected final byte getAnnotations() { return getByte(record + ANNOTATIONS); } @Override public int getAdditionalNameFlags(int standardFlags, IASTName name) { if ((standardFlags & PDOMName.IS_REFERENCE) == PDOMName.IS_REFERENCE) { return CPPVariableReadWriteFlags.getReadWriteFlags(name); } return 0; } }