blob: a90d9393397218f66c20cb2f5d9c9dfc664b94b0 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2007, 2016 Symbian 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:
* Andrew Ferguson (Symbian) - Initial implementation
* Markus Schorn (Wind River Systems)
* Sergey Prigogin (Google)
*******************************************************************************/
package org.eclipse.cdt.internal.core.index.composite.cpp;
import org.eclipse.cdt.core.CCorePlugin;
import org.eclipse.cdt.core.dom.ast.EScopeKind;
import org.eclipse.cdt.core.dom.ast.IArrayType;
import org.eclipse.cdt.core.dom.ast.IBasicType;
import org.eclipse.cdt.core.dom.ast.IBinding;
import org.eclipse.cdt.core.dom.ast.IPointerType;
import org.eclipse.cdt.core.dom.ast.IProblemBinding;
import org.eclipse.cdt.core.dom.ast.IQualifierType;
import org.eclipse.cdt.core.dom.ast.ISemanticProblem;
import org.eclipse.cdt.core.dom.ast.IType;
import org.eclipse.cdt.core.dom.ast.ITypedef;
import org.eclipse.cdt.core.dom.ast.IValue;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPAliasTemplate;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPAliasTemplateInstance;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPBinding;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassScope;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassTemplate;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassTemplatePartialSpecialization;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassTemplatePartialSpecializationSpecialization;
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.ICPPEnumScope;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPEnumeration;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPField;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPFieldTemplate;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunction;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunctionTemplate;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunctionType;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPMethod;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPNamespace;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPNamespaceAlias;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPNamespaceScope;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPParameter;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPParameterPackType;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPPointerToMemberType;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPReferenceType;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPSpecialization;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateArgument;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateDefinition;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateInstance;
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.ICPPUnaryTypeTransformation;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPUsingDeclaration;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPVariable;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPVariableInstance;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPVariableTemplate;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPVariableTemplatePartialSpecialization;
import org.eclipse.cdt.core.index.IIndex;
import org.eclipse.cdt.core.index.IIndexBinding;
import org.eclipse.cdt.core.index.IIndexMacroContainer;
import org.eclipse.cdt.internal.core.dom.parser.DependentValue;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPAliasTemplateInstance;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPArrayType;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPFunctionType;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPParameterPackType;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPPointerToMemberType;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPPointerType;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPQualifierType;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPReferenceType;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPUnaryTypeTransformation;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPUnknownMember;
import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPClassSpecializationScope;
import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPDeferredClassInstance;
import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPDeferredVariableInstance;
import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPEvaluation;
import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPInternalEnumerator;
import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPUnknownBinding;
import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPUnknownMember;
import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPUnknownMemberClass;
import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPUnknownMemberClassInstance;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPFunctionSet;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.EvalBinary;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.EvalBinaryTypeId;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.EvalBinding;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.EvalComma;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.EvalCompoundStatementExpression;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.EvalConditional;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.EvalFixed;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.EvalFunctionCall;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.EvalFunctionSet;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.EvalID;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.EvalInitList;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.EvalMemberAccess;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.EvalParameterPack;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.EvalTypeId;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.EvalUnary;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.EvalUnaryTypeID;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.TypeOfDependentExpression;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.TypeOfUnknownMember;
import org.eclipse.cdt.internal.core.index.CIndex;
import org.eclipse.cdt.internal.core.index.IIndexFragmentBinding;
import org.eclipse.cdt.internal.core.index.IIndexScope;
import org.eclipse.cdt.internal.core.index.composite.AbstractCompositeFactory;
import org.eclipse.cdt.internal.core.index.composite.CompositeMacroContainer;
import org.eclipse.cdt.internal.core.index.composite.CompositingNotImplementedError;
import org.eclipse.cdt.internal.core.index.composite.ICompositesFactory;
import org.eclipse.core.runtime.CoreException;
public class CPPCompositesFactory extends AbstractCompositeFactory {
public CPPCompositesFactory(IIndex index) {
super(index);
}
@Override
public IIndexScope getCompositeScope(IIndexScope rscope) {
try {
if (rscope == null) {
return null;
}
if (rscope.getKind() == EScopeKind.eGlobal) {
return rscope;
}
if (rscope instanceof ICPPClassScope) {
if (rscope instanceof ICPPClassSpecializationScope) {
return new CompositeCPPClassSpecializationScope(this, (IIndexFragmentBinding) rscope.getScopeBinding());
}
ICPPClassScope classScope = (ICPPClassScope) rscope;
return new CompositeCPPClassScope(this, findOneBinding(classScope.getClassType()));
}
if (rscope instanceof ICPPEnumScope) {
ICPPEnumScope enumScope = (ICPPEnumScope) rscope;
return new CompositeCPPEnumScope(this, findOneBinding(enumScope.getEnumerationType()));
}
if (rscope instanceof ICPPNamespaceScope) {
ICPPNamespace[] namespaces;
if (rscope instanceof CompositeCPPNamespace) {
// Avoid duplicating the search.
namespaces = ((CompositeCPPNamespace) rscope).namespaces;
} else {
namespaces = getNamespaces(rscope.getScopeBinding());
}
return new CompositeCPPNamespaceScope(this, namespaces);
}
throw new CompositingNotImplementedError(rscope.getClass().getName());
} catch (CoreException e) {
CCorePlugin.log(e);
throw new CompositingNotImplementedError(e.getMessage());
}
}
@Override
public IType getCompositeType(IType rtype) {
if (rtype instanceof IIndexFragmentBinding) {
return (IType) getCompositeBinding((IIndexFragmentBinding) rtype);
}
if (rtype instanceof ICPPFunctionType) {
ICPPFunctionType ft= (ICPPFunctionType) rtype;
IType r= ft.getReturnType();
IType r2= getCompositeType(r);
IType[] p= ft.getParameterTypes();
IType[] p2= getCompositeTypes(p);
if (r != r2 || p != p2) {
return new CPPFunctionType(r2, p2, ft.isConst(), ft.isVolatile(),
ft.hasRefQualifier(), ft.isRValueReference(), ft.takesVarArgs());
}
return ft;
}
if (rtype instanceof ICPPPointerToMemberType) {
ICPPPointerToMemberType pmt= (ICPPPointerToMemberType) rtype;
IType ct= pmt.getMemberOfClass();
IType ct2= getCompositeType(ct);
IType t= pmt.getType();
IType t2= getCompositeType(t);
if (ct != ct2 || t != t2) {
return new CPPPointerToMemberType(t2, ct2, pmt.isConst(), pmt.isVolatile(), pmt.isRestrict());
}
return pmt;
}
if (rtype instanceof IPointerType) {
IPointerType pt= (IPointerType) rtype;
IType r= pt.getType();
IType r2= getCompositeType(r);
if (r != r2) {
return new CPPPointerType(r2, pt.isConst(), pt.isVolatile(), pt.isRestrict());
}
return pt;
}
if (rtype instanceof ICPPReferenceType) {
ICPPReferenceType rt= (ICPPReferenceType) rtype;
IType r= rt.getType();
IType r2= getCompositeType(r);
if (r != r2) {
return new CPPReferenceType(r2, rt.isRValueReference());
}
return rt;
}
if (rtype instanceof ICPPParameterPackType) {
ICPPParameterPackType rt= (ICPPParameterPackType) rtype;
IType r= rt.getType();
IType r2= getCompositeType(r);
if (r != r2 && r2 != null) {
return new CPPParameterPackType(r2);
}
return rt;
}
if (rtype instanceof IQualifierType) {
IQualifierType qt= (IQualifierType) rtype;
IType r= qt.getType();
IType r2= getCompositeType(r);
if (r != r2) {
return new CPPQualifierType(r2, qt.isConst(), qt.isVolatile());
}
return qt;
}
if (rtype instanceof IArrayType) {
IArrayType at= (IArrayType) rtype;
IType r= at.getType();
IType r2= getCompositeType(r);
IValue v= at.getSize();
IValue v2= getCompositeValue(v);
if (r != r2 || v != v2) {
return new CPPArrayType(r2, v2);
}
return at;
}
if (rtype instanceof ICPPAliasTemplateInstance) {
ICPPAliasTemplateInstance instance = (ICPPAliasTemplateInstance) rtype;
ICPPAliasTemplate aliasTemplate = instance.getTemplateDefinition();
if (aliasTemplate instanceof IIndexFragmentBinding)
aliasTemplate = (ICPPAliasTemplate) getCompositeBinding((IIndexFragmentBinding) aliasTemplate);
IType aliasedType = getCompositeType(instance.getType());
return new CPPAliasTemplateInstance(instance.getNameCharArray(), aliasTemplate, aliasedType);
}
if (rtype instanceof TypeOfDependentExpression) {
TypeOfDependentExpression type= (TypeOfDependentExpression) rtype;
ICPPEvaluation e= type.getEvaluation();
ICPPEvaluation e2= getCompositeEvaluation(e);
if (e != e2)
return new TypeOfDependentExpression(e2);
return type;
}
if (rtype instanceof TypeOfUnknownMember) {
CPPUnknownMember member = ((TypeOfUnknownMember) rtype).getUnknownMember();
if (member instanceof IIndexFragmentBinding)
member = (CPPUnknownMember) getCompositeBinding((IIndexFragmentBinding) member);
return new TypeOfUnknownMember(member);
}
if (rtype instanceof ICPPUnaryTypeTransformation) {
ICPPUnaryTypeTransformation typeTransformation= (ICPPUnaryTypeTransformation) rtype;
IType operand = getCompositeType(typeTransformation.getOperand());
return new CPPUnaryTypeTransformation(typeTransformation.getOperator(), operand);
}
if (rtype instanceof IBasicType || rtype == null || rtype instanceof ISemanticProblem) {
return rtype;
}
throw new CompositingNotImplementedError();
}
public ICPPEvaluation getCompositeEvaluation(ICPPEvaluation eval) {
if (eval == null)
return null;
IBinding templateDefinition = eval.getTemplateDefinition();
IBinding compositeTemplateDefinition = templateDefinition instanceof IProblemBinding ?
templateDefinition :
getCompositeBinding((IIndexFragmentBinding) templateDefinition);
if (eval instanceof EvalBinary) {
EvalBinary e= (EvalBinary) eval;
ICPPEvaluation a = e.getArg1();
ICPPEvaluation b = e.getArg2();
ICPPEvaluation a2 = getCompositeEvaluation(a);
ICPPEvaluation b2 = getCompositeEvaluation(b);
if (a != a2 || b != b2 || templateDefinition != compositeTemplateDefinition)
e= new EvalBinary(e.getOperator(), a2, b2, compositeTemplateDefinition);
return e;
}
if (eval instanceof EvalBinaryTypeId) {
EvalBinaryTypeId e= (EvalBinaryTypeId) eval;
IType a = e.getType1();
IType b = e.getType2();
IType a2 = getCompositeType(a);
IType b2 = getCompositeType(b);
if (a != a2 || b != b2 || templateDefinition != compositeTemplateDefinition)
e= new EvalBinaryTypeId(e.getOperator(), a2, b2, compositeTemplateDefinition);
return e;
}
if (eval instanceof EvalBinding) {
EvalBinding e= (EvalBinding) eval;
ICPPFunction parameterOwner = e.getParameterOwner();
if (parameterOwner != null) {
IType b = e.getFixedType();
IBinding a2 = parameterOwner;
if (parameterOwner instanceof IIndexFragmentBinding) {
a2 = getCompositeBinding((IIndexFragmentBinding) parameterOwner);
}
IType b2 = getCompositeType(b);
if (parameterOwner != a2 || b != b2 || templateDefinition != compositeTemplateDefinition) {
int parameterPosition = e.getFunctionParameterPosition();
e= new EvalBinding((ICPPFunction) a2, parameterPosition, b2, compositeTemplateDefinition);
}
} else {
IBinding a = e.getBinding();
IType b = e.getFixedType();
IBinding a2 = a;
if (a instanceof IIndexFragmentBinding) {
a2 = getCompositeBinding((IIndexFragmentBinding) a);
}
IType b2 = getCompositeType(b);
if (a != a2 || b != b2 || templateDefinition != compositeTemplateDefinition)
e= new EvalBinding(a2, b2, compositeTemplateDefinition);
}
return e;
}
if (eval instanceof EvalComma) {
EvalComma e= (EvalComma) eval;
ICPPEvaluation[] a = e.getArguments();
ICPPEvaluation[] a2 = getCompositeEvaluationArray(a);
if (a != a2 || templateDefinition != compositeTemplateDefinition)
e= new EvalComma(a2, compositeTemplateDefinition);
return e;
}
if (eval instanceof EvalCompoundStatementExpression) {
EvalCompoundStatementExpression e= (EvalCompoundStatementExpression) eval;
ICPPEvaluation a = e.getLastEvaluation();
ICPPEvaluation a2 = getCompositeEvaluation(a);
if (a != a2 || templateDefinition != compositeTemplateDefinition)
e= new EvalCompoundStatementExpression(a2, compositeTemplateDefinition);
return e;
}
if (eval instanceof EvalConditional) {
EvalConditional e= (EvalConditional) eval;
ICPPEvaluation a = e.getCondition();
ICPPEvaluation b = e.getPositive();
ICPPEvaluation c = e.getNegative();
ICPPEvaluation a2 = getCompositeEvaluation(a);
ICPPEvaluation b2 = getCompositeEvaluation(b);
ICPPEvaluation c2 = getCompositeEvaluation(c);
if (a != a2 || b != b2 || c != c2 || templateDefinition != compositeTemplateDefinition)
e= new EvalConditional(a2, b2, c2, e.isPositiveThrows(), e.isNegativeThrows(), compositeTemplateDefinition);
return e;
}
if (eval instanceof EvalFixed) {
EvalFixed e= (EvalFixed) eval;
IType a = e.getType();
IValue b = e.getValue();
IType a2 = getCompositeType(a);
IValue b2= getCompositeValue(b);
if (a != a2 || b != b2 || templateDefinition != compositeTemplateDefinition)
e= new EvalFixed(a2, e.getValueCategory(), b2);
return e;
}
if (eval instanceof EvalFunctionCall) {
EvalFunctionCall e= (EvalFunctionCall) eval;
ICPPEvaluation[] a = e.getArguments();
ICPPEvaluation[] a2 = getCompositeEvaluationArray(a);
if (a != a2 || templateDefinition != compositeTemplateDefinition)
e= new EvalFunctionCall(a2, null, compositeTemplateDefinition);
return e;
}
if (eval instanceof EvalFunctionSet) {
EvalFunctionSet e= (EvalFunctionSet) eval;
final CPPFunctionSet fset = e.getFunctionSet();
if (fset != null) {
ICPPFunction[] a = fset.getBindings();
ICPPTemplateArgument[] b = fset.getTemplateArguments();
IType c = e.getImpliedObjectType();
ICPPFunction[] a2 = getCompositeFunctionArray(a);
ICPPTemplateArgument[] b2 = TemplateInstanceUtil.convert(this, b);
IType c2 = getCompositeType(c);
if (a != a2 || b != b2 || c != c2 || templateDefinition != compositeTemplateDefinition)
e= new EvalFunctionSet(new CPPFunctionSet(a2, b2, null), e.isQualified(), e.isAddressOf(),
c2, compositeTemplateDefinition);
}
return e;
}
if (eval instanceof EvalID) {
EvalID e= (EvalID) eval;
ICPPEvaluation a = e.getFieldOwner();
IBinding b = e.getNameOwner();
ICPPTemplateArgument[] c = e.getTemplateArgs();
ICPPEvaluation a2 = getCompositeEvaluation(a);
IBinding b2= b;
if (b instanceof IIndexFragmentBinding) {
b2 = getCompositeBinding((IIndexFragmentBinding) b);
} else if (b instanceof IType) {
b2 = (IBinding) getCompositeType((IType) b);
}
ICPPTemplateArgument[] c2 = TemplateInstanceUtil.convert(this, c);
if (a != a2 || b != b2 || c != c2 || templateDefinition != compositeTemplateDefinition)
e= new EvalID(a2, b2, e.getName(), e.isAddressOf(), e.isQualified(), e.isPointerDeref(), c2,
compositeTemplateDefinition);
return e;
}
if (eval instanceof EvalInitList) {
EvalInitList e= (EvalInitList) eval;
ICPPEvaluation[] a = e.getClauses();
ICPPEvaluation[] a2 = getCompositeEvaluationArray(a);
if (a != a2 || templateDefinition != compositeTemplateDefinition)
e= new EvalInitList(a2, compositeTemplateDefinition);
return e;
}
if (eval instanceof EvalMemberAccess) {
EvalMemberAccess e= (EvalMemberAccess) eval;
IType a = e.getOwnerType();
IBinding b = e.getMember();
ICPPEvaluation c = e.getOwnerEval();
IType a2= getCompositeType(a);
IBinding b2= b;
ICPPEvaluation c2 = c;
if (b instanceof IIndexFragmentBinding) {
b2= getCompositeBinding((IIndexFragmentBinding) b);
}
if (c != null) {
c2 = getCompositeEvaluation(c);
}
if (a != a2 || b != b2 || templateDefinition != compositeTemplateDefinition)
e= new EvalMemberAccess(a2, e.getOwnerValueCategory(), b2, c2, e.isPointerDeref(),
compositeTemplateDefinition);
return e;
}
if (eval instanceof EvalParameterPack) {
EvalParameterPack e = (EvalParameterPack) eval;
ICPPEvaluation a = e.getExpansionPattern();
ICPPEvaluation a2 = getCompositeEvaluation(a);
if (a != a2 || templateDefinition != compositeTemplateDefinition)
e = new EvalParameterPack(a2, compositeTemplateDefinition);
return e;
}
if (eval instanceof EvalTypeId) {
EvalTypeId e= (EvalTypeId) eval;
IType a = e.getInputType();
ICPPEvaluation[] b = e.getArguments();
IType a2= getCompositeType(a);
ICPPEvaluation[] b2 = getCompositeEvaluationArray(b);
if (a != a2 || b != b2 || templateDefinition != compositeTemplateDefinition)
e= new EvalTypeId(a2, compositeTemplateDefinition, e.representsNewExpression(),
e.usesBracedInitList(), b2);
return e;
}
if (eval instanceof EvalUnary) {
EvalUnary e= (EvalUnary) eval;
ICPPEvaluation a = e.getArgument();
ICPPEvaluation a2 = getCompositeEvaluation(a);
IBinding b= e.getAddressOfQualifiedNameBinding();
IBinding b2= b;
if (b instanceof IIndexFragmentBinding) {
b2= getCompositeBinding((IIndexFragmentBinding) b);
}
if (a != a2 || b != b2 || templateDefinition != compositeTemplateDefinition)
e= new EvalUnary(e.getOperator(), a2, b2, compositeTemplateDefinition);
return e;
}
if (eval instanceof EvalUnaryTypeID) {
EvalUnaryTypeID e= (EvalUnaryTypeID) eval;
IType a = e.getArgument();
IType a2 = getCompositeType(a);
if (a != a2 || templateDefinition != compositeTemplateDefinition)
e= new EvalUnaryTypeID(e.getOperator(), a2, compositeTemplateDefinition);
return e;
}
throw new CompositingNotImplementedError();
}
private ICPPEvaluation[] getCompositeEvaluationArray(ICPPEvaluation[] array) {
ICPPEvaluation[] array2= array;
for (int i = 0; i < array.length; i++) {
ICPPEvaluation a = array[i];
ICPPEvaluation a2= getCompositeEvaluation(a);
if (array != array2) {
array2[i]= a2;
} else if (a != a2) {
array2= new ICPPEvaluation[array.length];
System.arraycopy(array, 0, array2, 0, i);
array2[i]= a2;
}
}
return array2;
}
private ICPPFunction[] getCompositeFunctionArray(ICPPFunction[] array) {
ICPPFunction[] array2= array;
for (int i = 0; i < array.length; i++) {
ICPPFunction a = array[i];
ICPPFunction a2= (ICPPFunction) getCompositeBinding((IIndexFragmentBinding) a);
if (array != array2) {
array2[i]= a2;
} else if (a != a2) {
array2= new ICPPFunction[array.length];
System.arraycopy(array, 0, array2, 0, i);
array2[i]= a2;
}
}
return array2;
}
@Override
public IValue getCompositeValue(IValue v) {
if (v == null)
return null;
ICPPEvaluation eval = v.getEvaluation();
if (eval == null)
return v;
eval = getCompositeEvaluation(eval);
return DependentValue.create(eval);
}
private ICPPNamespace[] getNamespaces(IBinding rbinding) throws CoreException {
CIndex cindex = (CIndex) index;
IIndexBinding[] ibs = cindex.findEquivalentBindings(rbinding);
ICPPNamespace[] namespaces = new ICPPNamespace[ibs.length];
for (int i = 0; i < namespaces.length; i++)
namespaces[i] = (ICPPNamespace) ibs[i];
return namespaces;
}
IIndex getContext() {
return index;
}
protected IIndexFragmentBinding findOneBinding(IBinding binding) {
return findOneBinding(binding, false);
}
@Override
public IIndexBinding getCompositeBinding(IIndexFragmentBinding binding) {
IIndexBinding result;
try {
if (binding == null) {
result = null;
} else if (binding instanceof ICPPSpecialization) {
if (binding instanceof ICPPTemplateInstance) {
if (binding instanceof ICPPDeferredClassInstance) {
ICPPDeferredClassInstance def= (ICPPDeferredClassInstance) binding;
ICPPClassTemplate t0= def.getClassTemplate();
ICPPTemplateArgument[] args0= def.getTemplateArguments();
ICPPClassTemplate t= (ICPPClassTemplate) getCompositeType(t0);
ICPPTemplateArgument[] args = TemplateInstanceUtil.convert(this, args0);
return new CompositeCPPDeferredClassInstance(t, args);
} else if (binding instanceof ICPPDeferredVariableInstance) {
ICPPDeferredVariableInstance def= (ICPPDeferredVariableInstance) binding;
ICPPVariableTemplate t0= def.getTemplateDefinition();
ICPPTemplateArgument[] args0= def.getTemplateArguments();
ICPPVariableTemplate t=
(ICPPVariableTemplate) getCompositeBinding((IIndexFragmentBinding) t0);
ICPPTemplateArgument[] args = TemplateInstanceUtil.convert(this, args0);
return new CompositeCPPDeferredVariableInstance(t, args);
} else {
if (binding instanceof ICPPClassType) {
return new CompositeCPPClassInstance(this, (ICPPClassType) findOneBinding(binding));
} else if (binding instanceof ICPPConstructor) {
return new CompositeCPPConstructorInstance(this, (ICPPConstructor) binding);
} else if (binding instanceof ICPPMethod) {
return new CompositeCPPMethodInstance(this, (ICPPMethod) binding);
} else if (binding instanceof ICPPFunction) {
return new CompositeCPPFunctionInstance(this, (ICPPFunction) binding);
} else if (binding instanceof ICPPField) {
return new CompositeCPPFieldInstance(this, (ICPPVariableInstance) binding);
} else if (binding instanceof ICPPVariable) {
return new CompositeCPPVariableInstance(this, (ICPPVariableInstance) binding);
} else {
throw new CompositingNotImplementedError("Composite binding unavailable for " + binding + " " + binding.getClass()); //$NON-NLS-1$ //$NON-NLS-2$
}
}
} else if (binding instanceof ICPPTemplateDefinition) {
if (binding instanceof ICPPClassTemplatePartialSpecialization) {
return new CompositeCPPClassTemplatePartialSpecializationSpecialization(this, (ICPPClassTemplatePartialSpecializationSpecialization) binding);
} else if (binding instanceof ICPPClassType) {
return new CompositeCPPClassTemplateSpecialization(this, (ICPPClassType) binding);
} else if (binding instanceof ICPPConstructor) {
return new CompositeCPPConstructorTemplateSpecialization(this, (ICPPConstructor) binding);
} else if (binding instanceof ICPPMethod) {
return new CompositeCPPMethodTemplateSpecialization(this, (ICPPMethod) binding);
} else if (binding instanceof ICPPFunction) {
return new CompositeCPPFunctionTemplateSpecialization(this, (ICPPFunction) binding);
} else if (binding instanceof ICPPAliasTemplate) {
return new CompositeCPPAliasTemplateSpecialization(this, (ICPPAliasTemplate) binding);
} else {
throw new CompositingNotImplementedError("Composite binding unavailable for " + binding + " " + binding.getClass()); //$NON-NLS-1$ //$NON-NLS-2$
}
} else {
if (binding instanceof ICPPClassType) {
return new CompositeCPPClassSpecialization(this, (ICPPClassType) findOneBinding(binding));
} else if (binding instanceof ICPPConstructor) {
return new CompositeCPPConstructorSpecialization(this, (ICPPConstructor) findOneBinding(binding, true));
} else if (binding instanceof ICPPMethod) {
return new CompositeCPPMethodSpecialization(this, (ICPPMethod) findOneBinding(binding, true));
} else if (binding instanceof ICPPFunction) {
return new CompositeCPPFunctionSpecialization(this, (ICPPFunction) findOneBinding(binding, true));
} else if (binding instanceof ICPPField) {
return new CompositeCPPField(this, (ICPPField) binding);
} else if (binding instanceof ICPPParameter) {
return new CompositeCPPParameterSpecialization(this, (ICPPParameter) binding);
} else if (binding instanceof ITypedef) {
return new CompositeCPPTypedefSpecialization(this, (ICPPBinding) binding);
} else if (binding instanceof ICPPUsingDeclaration) {
return new CompositeCPPUsingDeclarationSpecialization(this, (ICPPUsingDeclaration) binding);
} else if (binding instanceof ICPPEnumeration) {
return new CompositeCPPEnumerationSpecialization(this, (ICPPEnumeration) binding);
} else if (binding instanceof ICPPInternalEnumerator) {
return new CompositeCPPEnumeratorSpecialization(this, (ICPPInternalEnumerator) binding);
} else {
throw new CompositingNotImplementedError("Composite binding unavailable for " + binding + " " + binding.getClass()); //$NON-NLS-1$ //$NON-NLS-2$
}
}
} else if (binding instanceof ICPPClassTemplatePartialSpecialization) {
return new CompositeCPPClassTemplatePartialSpecialization(this, (ICPPClassTemplatePartialSpecialization) findOneBinding(binding));
} else if (binding instanceof ICPPVariableTemplatePartialSpecialization) {
if (binding instanceof ICPPField) {
return new CompositeCPPFieldTemplatePartialSpecialization(this, (ICPPVariableTemplatePartialSpecialization) binding);
} else {
return new CompositeCPPVariableTemplatePartialSpecialization(this, (ICPPVariableTemplatePartialSpecialization) binding);
}
} else if (binding instanceof ICPPTemplateParameter) {
if (binding instanceof ICPPTemplateTypeParameter) {
result = new CompositeCPPTemplateTypeParameter(this, (ICPPTemplateTypeParameter) binding);
} else if (binding instanceof ICPPTemplateNonTypeParameter) {
result = new CompositeCPPTemplateNonTypeParameter(this, (ICPPTemplateNonTypeParameter) binding);
} else if (binding instanceof ICPPTemplateTemplateParameter) {
result = new CompositeCPPTemplateTemplateParameter(this, (ICPPTemplateTemplateParameter) binding);
} else {
throw new CompositingNotImplementedError("Composite binding unavailable for " + binding + " " + binding.getClass()); //$NON-NLS-1$ //$NON-NLS-2$
}
} else if (binding instanceof ICPPTemplateDefinition) {
if (binding instanceof ICPPClassTemplate) {
ICPPClassType def= (ICPPClassType) findOneBinding(binding);
return new CompositeCPPClassTemplate(this, def);
} else if (binding instanceof ICPPConstructor) {
return new CompositeCPPConstructorTemplate(this, (ICPPConstructor) binding);
} else if (binding instanceof ICPPMethod) {
return new CompositeCPPMethodTemplate(this, (ICPPMethod) binding);
} else if (binding instanceof ICPPFunctionTemplate) {
return new CompositeCPPFunctionTemplate(this, (ICPPFunction) binding);
} else if (binding instanceof ICPPAliasTemplate) {
return new CompositeCPPAliasTemplate(this, (ICPPBinding) binding);
} else if (binding instanceof ICPPFieldTemplate) {
ICPPField def = (ICPPField) findOneBinding(binding);
return new CompositeCPPFieldTemplate(this, def);
} else if (binding instanceof ICPPVariableTemplate) {
ICPPVariable def = (ICPPVariable) findOneBinding(binding);
return new CompositeCPPVariableTemplate(this, def);
} else {
throw new CompositingNotImplementedError("Composite binding unavailable for " + binding + " " + binding.getClass()); //$NON-NLS-1$ //$NON-NLS-2$
}
} else if (binding instanceof ICPPUnknownBinding) {
if (binding instanceof ICPPUnknownMember) {
ICPPUnknownMember def= (ICPPUnknownMember) binding;
IType b= getCompositeType(def.getOwnerType());
if (binding instanceof ICPPUnknownMemberClass) {
if (binding instanceof ICPPUnknownMemberClassInstance) {
ICPPTemplateArgument[] args0= ((ICPPUnknownMemberClassInstance) binding).getArguments();
ICPPTemplateArgument[] args = TemplateInstanceUtil.convert(this, args0);
return new CompositeCPPUnknownMemberClassInstance(b, def.getNameCharArray(), args);
} else {
return new CompositeCPPUnknownMemberClass(b, def.getNameCharArray());
}
} else if (binding instanceof ICPPField) {
return new CompositeCPPUnknownField(b, def.getNameCharArray());
} else if (binding instanceof ICPPMethod) {
return new CompositeCPPUnknownMethod(b, def.getNameCharArray());
}
}
throw new CompositingNotImplementedError("Composite binding unavailable for " + binding + " " + binding.getClass()); //$NON-NLS-1$ //$NON-NLS-2$
} else if (binding instanceof ICPPParameter) {
result = new CompositeCPPParameter(this, (ICPPParameter) binding);
} else if (binding instanceof ICPPField) {
result = new CompositeCPPField(this, (ICPPField) binding);
} else if (binding instanceof ICPPVariable) {
result = new CompositeCPPVariable(this, (ICPPVariable) binding);
} else if (binding instanceof ICPPClassType) {
ICPPClassType def = (ICPPClassType) findOneBinding(binding);
result = def == null ? null : new CompositeCPPClassType(this, def);
} else if (binding instanceof ICPPConstructor) {
result = new CompositeCPPConstructor(this, (ICPPConstructor) binding);
} else if (binding instanceof ICPPMethod) {
result = new CompositeCPPMethod(this, (ICPPMethod) binding);
} else if (binding instanceof ICPPNamespaceAlias) {
result = new CompositeCPPNamespaceAlias(this, (ICPPNamespaceAlias) binding);
} else if (binding instanceof ICPPNamespace) {
ICPPNamespace[] ns = getNamespaces(binding);
result = ns.length == 0 ? null : new CompositeCPPNamespace(this, ns);
} else if (binding instanceof ICPPUsingDeclaration) {
result = new CompositeCPPUsingDeclaration(this, (ICPPUsingDeclaration) binding);
} else if (binding instanceof ICPPEnumeration) {
ICPPEnumeration def = (ICPPEnumeration) findOneBinding(binding);
result = def == null ? null : new CompositeCPPEnumeration(this, def);
} else if (binding instanceof ICPPFunction) {
result = new CompositeCPPFunction(this, (ICPPFunction) binding);
} else if (binding instanceof ICPPInternalEnumerator) {
result = new CompositeCPPEnumerator(this, (ICPPInternalEnumerator) binding);
} else if (binding instanceof ICPPAliasTemplateInstance) {
return new CompositeCPPAliasTemplateInstance(this, (ICPPBinding) binding);
} else if (binding instanceof ITypedef) {
result = new CompositeCPPTypedef(this, (ICPPBinding) binding);
} else if (binding instanceof IIndexMacroContainer) {
result= new CompositeMacroContainer(this, binding);
} else {
throw new CompositingNotImplementedError("Composite binding unavailable for " + binding + " " + binding.getClass()); //$NON-NLS-1$ //$NON-NLS-2$
}
} catch (CoreException e) {
CCorePlugin.log(e);
throw new CompositingNotImplementedError(e.getMessage());
}
return result;
}
private static class Key {
final long i;
final int j;
final long k;
public Key(long id1, int id2, long id3) {
i= id1;
j= id2;
k= id3;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + (int) (i ^ (i >>> 32));
result = prime * result + j;
result = prime * result + (int) k;
return result;
}
@Override
public boolean equals(Object obj) {
if (obj instanceof Key) {
Key other = (Key) obj;
return i == other.i && j == other.j && k == other.k;
}
return false;
}
}
public static Object createInstanceCacheKey(ICompositesFactory cf, IIndexFragmentBinding rbinding) {
return new Key(Thread.currentThread().getId(), cf.hashCode(), rbinding.getBindingID());
}
public static Object createSpecializationKey(ICompositesFactory cf,IIndexFragmentBinding rbinding) {
return new Key(Thread.currentThread().getId(), cf.hashCode(), rbinding.getBindingID()+1);
}
}