blob: 7abccb7072cc4d07bd68d72b61b7b9fcccdcc27c [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2008, 2013 Wind River Systems, Inc. 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:
* Markus Schorn - initial API and implementation
* Thomas Corbat (IFS)
*******************************************************************************/
package org.eclipse.cdt.internal.core.pdom.dom.cpp;
import org.eclipse.cdt.core.CCorePlugin;
import org.eclipse.cdt.core.dom.IPDOMVisitor;
import org.eclipse.cdt.core.dom.ast.DOMException;
import org.eclipse.cdt.core.dom.ast.IBinding;
import org.eclipse.cdt.core.dom.ast.IField;
import org.eclipse.cdt.core.dom.ast.IScope;
import org.eclipse.cdt.core.dom.ast.IType;
import org.eclipse.cdt.core.dom.ast.ITypedef;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPBase;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassTemplatePartialSpecialization;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassType;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPConstructor;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPField;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPMethod;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPScope;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateArgument;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateNonTypeParameter;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateParameter;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateTemplateParameter;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateTypeParameter;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPUsingDeclaration;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTName;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPTemplateTypeArgument;
import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPDeferredClassInstance;
import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPUnknownBinding;
import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPUnknownType;
import org.eclipse.cdt.internal.core.index.IIndexCPPBindingConstants;
import org.eclipse.cdt.internal.core.index.IIndexType;
import org.eclipse.cdt.internal.core.pdom.db.Database;
import org.eclipse.cdt.internal.core.pdom.db.PDOMNodeLinkedList;
import org.eclipse.cdt.internal.core.pdom.dom.PDOMLinkage;
import org.eclipse.cdt.internal.core.pdom.dom.PDOMNode;
import org.eclipse.cdt.internal.core.pdom.dom.cpp.PDOMCPPLinkage.ConfigureTemplateParameters;
import org.eclipse.core.runtime.CoreException;
/**
* Implementation of template template parameters for the index.
*/
public class PDOMCPPTemplateTemplateParameter extends PDOMCPPBinding
implements ICPPTemplateTemplateParameter, ICPPUnknownBinding, ICPPUnknownType, IIndexType,
IPDOMCPPTemplateParameter, IPDOMCPPTemplateParameterOwner {
private static final int PACK_BIT = 1 << 31;
private static final int DEFAULT_TYPE = PDOMCPPBinding.RECORD_SIZE;
private static final int MEMBERLIST = DEFAULT_TYPE + Database.TYPE_SIZE;
private static final int PARAMETERID= MEMBERLIST + Database.PTR_SIZE;
private static final int PARAMETERS= PARAMETERID + 4;
@SuppressWarnings("hiding")
protected static final int RECORD_SIZE = PARAMETERS + Database.PTR_SIZE;
private PDOMCPPUnknownScope fUnknownScope; // No need for volatile, PDOMCPPUnknownScope protects its fields.
private int fCachedParamID= -1;
private volatile IPDOMCPPTemplateParameter[] params;
public PDOMCPPTemplateTemplateParameter(PDOMLinkage linkage, PDOMNode parent, ICPPTemplateTemplateParameter param)
throws CoreException, DOMException {
super(linkage, parent, param.getNameCharArray());
final Database db = getDB();
int id= param.getParameterID();
if (param.isParameterPack()) {
id |= PACK_BIT;
}
db.putInt(record + PARAMETERID, id);
final ICPPTemplateParameter[] origParams= param.getTemplateParameters();
final IPDOMCPPTemplateParameter[] params = PDOMTemplateParameterArray.createPDOMTemplateParameters(linkage, this, origParams);
((PDOMCPPLinkage)linkage).new ConfigureTemplateParameters(origParams, params);
long rec= PDOMTemplateParameterArray.putArray(db, params);
getDB().putRecPtr(record + PARAMETERS, rec);
}
public PDOMCPPTemplateTemplateParameter(PDOMLinkage linkage, long bindingRecord) {
super(linkage, bindingRecord);
}
@Override
protected int getRecordSize() {
return RECORD_SIZE;
}
@Override
public int getNodeType() {
return IIndexCPPBindingConstants.CPP_TEMPLATE_TEMPLATE_PARAMETER;
}
@Override
public short getParameterPosition() {
return (short) getParameterID();
}
@Override
public short getTemplateNestingLevel() {
readParamID();
return (short)(getParameterID() >> 16);
}
@Override
public boolean isParameterPack() {
readParamID();
return (fCachedParamID & PACK_BIT) != 0;
}
@Override
public int getParameterID() {
readParamID();
return fCachedParamID & ~PACK_BIT;
}
private void readParamID() {
if (fCachedParamID == -1) {
try {
final Database db = getDB();
fCachedParamID= db.getInt(record + PARAMETERID);
} catch (CoreException e) {
CCorePlugin.log(e);
fCachedParamID= Integer.MAX_VALUE;
}
}
}
@Override
public void addChild(PDOMNode member) throws CoreException {
PDOMNodeLinkedList list = new PDOMNodeLinkedList(getLinkage(), record + MEMBERLIST);
list.addMember(member);
}
@Override
public void accept(IPDOMVisitor visitor) throws CoreException {
PDOMNodeLinkedList list = new PDOMNodeLinkedList(getLinkage(), record + MEMBERLIST);
list.accept(visitor);
}
@Override
public boolean isSameType(IType type) {
if (type instanceof ITypedef) {
return type.isSameType(this);
}
if (!(type instanceof ICPPTemplateTemplateParameter))
return false;
return getParameterID() == ((ICPPTemplateParameter) type).getParameterID();
}
@Override
public IType getDefault() {
try {
return getLinkage().loadType(record + DEFAULT_TYPE);
} catch (CoreException e) {
CCorePlugin.log(e);
}
return null;
}
@Override
public ICPPTemplateArgument getDefaultValue() {
IType d= getDefault();
if (d == null)
return null;
return new CPPTemplateTypeArgument(d);
}
@Override
public Object clone() {
throw new UnsupportedOperationException();
}
@Override
public ICPPScope asScope() {
if (fUnknownScope == null) {
fUnknownScope= new PDOMCPPUnknownScope(this, new CPPASTName(getNameCharArray()));
}
return fUnknownScope;
}
@Override
public void configure(ICPPTemplateParameter param) {
try {
ICPPTemplateArgument val= param.getDefaultValue();
if (val != null) {
IType dflt= val.getTypeValue();
if (dflt != null) {
getLinkage().storeType(record + DEFAULT_TYPE, dflt);
}
}
} catch (CoreException e) {
CCorePlugin.log(e);
}
}
@Override
public void update(PDOMLinkage linkage, IBinding newBinding) throws CoreException {
if (newBinding instanceof ICPPTemplateTemplateParameter) {
final Database db = getDB();
ICPPTemplateTemplateParameter ttp= (ICPPTemplateTemplateParameter) newBinding;
updateName(newBinding.getNameCharArray());
IType newDefault= null;
try {
newDefault = ttp.getDefault();
} catch (DOMException e) {
// ignore
}
if (newDefault != null) {
linkage.storeType(record + DEFAULT_TYPE, newDefault);
}
long oldRec= db.getRecPtr(record + PARAMETERS);
IPDOMCPPTemplateParameter[] oldParams= getTemplateParameters();
try {
params= PDOMTemplateParameterArray.createPDOMTemplateParameters(getLinkage(), this, ttp.getTemplateParameters());
((PDOMCPPLinkage)linkage).new ConfigureTemplateParameters(ttp.getTemplateParameters(), params);
long newRec= PDOMTemplateParameterArray.putArray(db, params);
db.putRecPtr(record + PARAMETERS, newRec);
if (oldRec != 0)
db.free(oldRec);
for (IPDOMCPPTemplateParameter opar : oldParams) {
opar.forceDelete(linkage);
}
} catch (DOMException e) {
}
}
}
@Override
public void forceDelete(PDOMLinkage linkage) throws CoreException {
getDBName().delete();
linkage.storeType(record + DEFAULT_TYPE, null);
final Database db= getDB();
long oldRec= db.getRecPtr(record + PARAMETERS);
IPDOMCPPTemplateParameter[] oldParams= getTemplateParameters();
if (oldRec != 0)
db.free(oldRec);
for (IPDOMCPPTemplateParameter opar : oldParams) {
opar.forceDelete(linkage);
}
}
@Override
public IPDOMCPPTemplateParameter[] getTemplateParameters() {
if (params == null) {
try {
long rec= getDB().getRecPtr(record + PARAMETERS);
if (rec == 0) {
params= IPDOMCPPTemplateParameter.EMPTY_ARRAY;
} else {
params= PDOMTemplateParameterArray.getArray(this, rec);
}
} catch (CoreException e) {
CCorePlugin.log(e);
params = IPDOMCPPTemplateParameter.EMPTY_ARRAY;
}
}
return params;
}
@Override
public ICPPClassTemplatePartialSpecialization[] getPartialSpecializations() {
return ICPPClassTemplatePartialSpecialization.EMPTY_ARRAY;
}
@Override
public IField findField(String name) {
return null;
}
@Override
public ICPPMethod[] getAllDeclaredMethods() {
return ICPPMethod.EMPTY_CPPMETHOD_ARRAY;
}
@Override
public ICPPBase[] getBases() {
return ICPPBase.EMPTY_BASE_ARRAY;
}
@Override
public ICPPConstructor[] getConstructors() {
return ICPPConstructor.EMPTY_CONSTRUCTOR_ARRAY;
}
@Override
public ICPPField[] getDeclaredFields() {
return ICPPField.EMPTY_CPPFIELD_ARRAY;
}
@Override
public ICPPMethod[] getDeclaredMethods() {
return ICPPMethod.EMPTY_CPPMETHOD_ARRAY;
}
@Override
public IField[] getFields() {
return ICPPField.EMPTY_CPPFIELD_ARRAY;
}
@Override
public IBinding[] getFriends() {
return IBinding.EMPTY_BINDING_ARRAY;
}
@Override
public ICPPMethod[] getMethods() {
return ICPPMethod.EMPTY_CPPMETHOD_ARRAY;
}
@Override
public ICPPClassType[] getNestedClasses() {
return ICPPClassType.EMPTY_CLASS_ARRAY;
}
@Override
public ICPPUsingDeclaration[] getUsingDeclarations() {
return ICPPUsingDeclaration.EMPTY_USING_DECL_ARRAY;
}
@Override
public IScope getCompositeScope() {
return asScope();
}
@Override
public int getKey() {
return 0;
}
@Override
public boolean isAnonymous() {
return false;
}
@Override
public boolean isFinal() {
return false;
}
@Override
public ICPPTemplateParameter adaptTemplateParameter(ICPPTemplateParameter param) {
int pos = param.getParameterPosition();
ICPPTemplateParameter[] pars = getTemplateParameters();
if (pars == null || pos >= pars.length)
return null;
ICPPTemplateParameter result= pars[pos];
if (param instanceof ICPPTemplateTypeParameter) {
if (result instanceof ICPPTemplateTypeParameter)
return result;
} else if (param instanceof ICPPTemplateNonTypeParameter) {
if (result instanceof ICPPTemplateNonTypeParameter)
return result;
} else if (param instanceof ICPPTemplateTemplateParameter) {
if (result instanceof ICPPTemplateTemplateParameter)
return result;
}
return null;
}
@Override
public ICPPDeferredClassInstance asDeferredInstance() {
return null;
}
@Override
public int getVisibility(IBinding member) {
throw new IllegalArgumentException(member.getName() + " is not a member of " + getName()); //$NON-NLS-1$
}
}