/******************************************************************************* * 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: * QNX - Initial API and implementation * Markus Schorn (Wind River Systems) * Sergey Prigogin (Google) *******************************************************************************/ package org.eclipse.cdt.internal.core.pdom.dom; import org.eclipse.cdt.core.CCorePlugin; import org.eclipse.cdt.core.dom.ast.IASTFileLocation; import org.eclipse.cdt.core.dom.ast.IASTName; import org.eclipse.cdt.core.dom.ast.IASTPreprocessorIncludeStatement; import org.eclipse.cdt.core.index.IIndexFile; import org.eclipse.cdt.core.index.IIndexName; import org.eclipse.cdt.core.index.IndexLocationFactory; import org.eclipse.cdt.core.parser.util.CharArrayUtils; import org.eclipse.cdt.internal.core.index.IIndexFragment; import org.eclipse.cdt.internal.core.index.IIndexFragmentBinding; import org.eclipse.cdt.internal.core.index.IIndexFragmentName; import org.eclipse.cdt.internal.core.pdom.PDOM; import org.eclipse.cdt.internal.core.pdom.db.Database; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IPath; /** * Represents declarations, definitions and references to bindings, except for macros. */ public final class PDOMMacroReferenceName implements IIndexFragmentName, IASTFileLocation { private final PDOMLinkage linkage; private final long record; private static final int FILE_REC_OFFSET = 0; private static final int FILE_NEXT_OFFSET = 4; private static final int CONTAINER_REC_OFFSET = 8; private static final int CONTAINER_PREV_OFFSET = 12; private static final int CONTAINER_NEXT_OFFSET = 16; private static final int NODE_OFFSET_OFFSET = 20; private static final int NODE_LENGTH_OFFSET = 24; private static final int RECORD_SIZE = 26; public PDOMMacroReferenceName(PDOMLinkage linkage, IASTName name, PDOMFile file, PDOMMacroContainer container) throws CoreException { this.linkage = linkage; Database db = linkage.getDB(); record = db.malloc(RECORD_SIZE); db.putRecPtr(record + CONTAINER_REC_OFFSET, container.getRecord()); db.putRecPtr(record + FILE_REC_OFFSET, file.getRecord()); // Record our location in the file IASTFileLocation fileloc = name.getFileLocation(); db.putInt(record + NODE_OFFSET_OFFSET, fileloc.getNodeOffset()); db.putShort(record + NODE_LENGTH_OFFSET, (short) fileloc.getNodeLength()); container.addReference(this); } public PDOMMacroReferenceName(PDOMLinkage linkage, long nameRecord) { this.linkage = linkage; this.record = nameRecord; } public long getRecord() { return record; } public PDOM getPDOM() { return linkage.getPDOM(); } private long getRecField(int offset) throws CoreException { return linkage.getDB().getRecPtr(record + offset); } private void setRecField(int offset, long fieldrec) throws CoreException { linkage.getDB().putRecPtr(record + offset, fieldrec); } public PDOMMacroContainer getContainer() throws CoreException { long bindingrec = getRecField(CONTAINER_REC_OFFSET); return new PDOMMacroContainer(linkage, bindingrec); } private PDOMMacroReferenceName getNameField(int offset) throws CoreException { long namerec = getRecField(offset); return namerec != 0 ? new PDOMMacroReferenceName(linkage, namerec) : null; } private void setNameField(int offset, PDOMMacroReferenceName name) throws CoreException { long namerec = name != null ? name.getRecord() : 0; setRecField(offset, namerec); } PDOMMacroReferenceName getPrevInContainer() throws CoreException { return getNameField(CONTAINER_PREV_OFFSET); } void setPrevInContainer(PDOMMacroReferenceName name) throws CoreException { setNameField(CONTAINER_PREV_OFFSET, name); } public PDOMMacroReferenceName getNextInContainer() throws CoreException { return getNameField(CONTAINER_NEXT_OFFSET); } void setNextInContainer(PDOMMacroReferenceName name) throws CoreException { setNameField(CONTAINER_NEXT_OFFSET, name); } public PDOMFile getFile() throws CoreException { long filerec = linkage.getDB().getRecPtr(record + FILE_REC_OFFSET); return filerec != 0 ? new PDOMFile(linkage, filerec) : null; } public long getFileRecord() throws CoreException { return linkage.getDB().getRecPtr(record + FILE_REC_OFFSET); } void setFile(PDOMFile file) throws CoreException { linkage.getDB().putRecPtr(record + FILE_REC_OFFSET, file != null ? file.getRecord() : 0); } PDOMMacroReferenceName getNextInFile() throws CoreException { return getNameField(FILE_NEXT_OFFSET); } void setNextInFile(PDOMMacroReferenceName name) throws CoreException { setNameField(FILE_NEXT_OFFSET, name); } /** * @deprecated use {@link #getSimpleID()}. */ @Deprecated public char[] toCharArray() { return getSimpleID(); } public char[] getSimpleID() { try { return getContainer().getNameCharArray(); } catch (CoreException e) { CCorePlugin.log(e); return CharArrayUtils.EMPTY; } } @Override public String toString() { return new String(getSimpleID()); } public boolean isBaseSpecifier() throws CoreException { return false; } public boolean couldBePolymorphicMethodCall() throws CoreException { return false; } public boolean isInlineNamespaceDefinition() { return false; } public boolean isReadAccess() throws CoreException { return false; } public boolean isWriteAccess() throws CoreException { return false; } public boolean isDeclaration() { return false; } public boolean isReference() { return true; } public boolean isDefinition() { return false; } public IASTFileLocation getFileLocation() { return this; } public String getFileName() { try { IIndexFile file = getFile(); if (file == null) { return null; } // We need to specify what this method can return to know // how to implement this. Existing implementations return // the absolute path, so here we attempt to do the same. IPath location = IndexLocationFactory.getAbsolutePath(file.getLocation()); return location != null ? location.toOSString() : null; } catch (CoreException e) { CCorePlugin.log(e); } return null; } public int getStartingLineNumber() { return 0; } public int getEndingLineNumber() { return 0; } public IASTPreprocessorIncludeStatement getContextInclusionStatement() { return null; } public IASTFileLocation asFileLocation() { return this; } public int getNodeLength() { try { return (linkage.getDB().getShort(record + NODE_LENGTH_OFFSET)) & 0xffff; } catch (CoreException e) { CCorePlugin.log(e); return 0; } } public int getNodeOffset() { try { return linkage.getDB().getInt(record + NODE_OFFSET_OFFSET); } catch (CoreException e) { CCorePlugin.log(e); return 0; } } public void delete() throws CoreException { // Delete from the binding chain PDOMMacroReferenceName prevName = getPrevInContainer(); PDOMMacroReferenceName nextName = getNextInContainer(); if (prevName != null) { prevName.setNextInContainer(nextName); } else { getContainer().setFirstReference(nextName); } if (nextName != null) nextName.setPrevInContainer(prevName); // Delete our record linkage.getDB().free(record); } public IIndexFragment getIndexFragment() { return linkage.getPDOM(); } public IIndexName[] getEnclosedNames() throws CoreException { return IIndexName.EMPTY_ARRAY; } public IIndexFragmentBinding getBinding() throws CoreException { return getContainer(); } public IIndexName getEnclosingDefinition() throws CoreException { return null; } }