/******************************************************************************* * Copyright (c) 2007, 2015 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 * Sergey Prigogin (Google) *******************************************************************************/ package org.eclipse.cdt.internal.core.index.composite.c; import org.eclipse.cdt.core.dom.ast.EScopeKind; import org.eclipse.cdt.core.dom.ast.IBasicType; import org.eclipse.cdt.core.dom.ast.ICompositeType; import org.eclipse.cdt.core.dom.ast.IEnumeration; import org.eclipse.cdt.core.dom.ast.IEnumerator; import org.eclipse.cdt.core.dom.ast.IField; import org.eclipse.cdt.core.dom.ast.IFunction; import org.eclipse.cdt.core.dom.ast.IFunctionType; import org.eclipse.cdt.core.dom.ast.IParameter; 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.IVariable; import org.eclipse.cdt.core.dom.ast.c.ICArrayType; import org.eclipse.cdt.core.dom.ast.c.ICCompositeTypeScope; import org.eclipse.cdt.core.dom.ast.c.ICPointerType; import org.eclipse.cdt.core.dom.ast.c.ICQualifierType; 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.c.CArrayType; import org.eclipse.cdt.internal.core.dom.parser.c.CFunctionType; import org.eclipse.cdt.internal.core.dom.parser.c.CPointerType; import org.eclipse.cdt.internal.core.dom.parser.c.CQualifierType; 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; public class CCompositesFactory extends AbstractCompositeFactory { public CCompositesFactory(IIndex index) { super(index); } @Override public IIndexScope getCompositeScope(IIndexScope rscope) { if (rscope == null) return null; if (rscope.getKind() == EScopeKind.eGlobal) return rscope; if (rscope instanceof ICCompositeTypeScope) { ICCompositeTypeScope cscope = (ICCompositeTypeScope) rscope; IIndexFragmentBinding rbinding = (IIndexFragmentBinding) cscope.getCompositeType(); return (IIndexScope) ((ICompositeType) getCompositeBinding(rbinding)).getCompositeScope(); } throw new CompositingNotImplementedError(); } @Override public IType getCompositeType(IType rtype) { if (rtype instanceof IIndexFragmentBinding) { return (IType) getCompositeBinding((IIndexFragmentBinding) rtype); } if (rtype instanceof IFunctionType) { IFunctionType ft= (IFunctionType) rtype; IType r= ft.getReturnType(); IType r2= getCompositeType(r); IType[] p= ft.getParameterTypes(); IType[] p2= getCompositeTypes(p); boolean takesVarargs = ft.takesVarArgs(); if (r != r2 || p != p2) { return new CFunctionType(r2, p2, takesVarargs); } return ft; } if (rtype instanceof ICPointerType) { ICPointerType pt= (ICPointerType) rtype; IType r= pt.getType(); IType r2= getCompositeType(r); if (r != r2) { int q= 0; if (pt.isConst()) q |= CPointerType.IS_CONST; if (pt.isVolatile()) q |= CPointerType.IS_VOLATILE; if (pt.isRestrict()) q |= CPointerType.IS_RESTRICT; return new CPointerType(r2, q); } return pt; } if (rtype instanceof ICQualifierType) { ICQualifierType qt= (ICQualifierType) rtype; IType r= qt.getType(); IType r2= getCompositeType(r); if (r != r2) { return new CQualifierType(r2, qt.isConst(), qt.isVolatile(), qt.isRestrict()); } return qt; } if (rtype instanceof ICArrayType) { ICArrayType at= (ICArrayType) rtype; IType r= at.getType(); IType r2= getCompositeType(r); IValue v= at.getSize(); IValue v2= getCompositeValue(v); if (r != r2 || v != v2) { CArrayType at2 = new CArrayType(r2, at.isConst(), at.isVolatile(), at.isRestrict(), v2); at2.setIsStatic(at.isStatic()); at2.setIsVariableLength(at.isVariableLength()); } return at; } if (rtype instanceof IBasicType || rtype instanceof ISemanticProblem || rtype == null) { return rtype; } throw new CompositingNotImplementedError(); } @Override public IValue getCompositeValue(IValue v) { return v; } /* * @see org.eclipse.cdt.internal.core.index.composite.cpp.ICompositesFactory#getCompositeBinding(org.eclipse.cdt.core.index.IIndex, org.eclipse.cdt.core.dom.ast.IBinding) */ @Override public IIndexBinding getCompositeBinding(IIndexFragmentBinding rbinding) { IIndexBinding result; if (rbinding == null) { result = null; } else if (rbinding instanceof IParameter) { result = new CompositeCParameter(this, rbinding); } else if (rbinding instanceof IField) { result = new CompositeCField(this, rbinding); } else if (rbinding instanceof IVariable) { result = new CompositeCVariable(this, rbinding); } else if (rbinding instanceof ICompositeType) { result = new CompositeCStructure(this, findOneBinding(rbinding, false)); } else if (rbinding instanceof IEnumeration) { result = new CompositeCEnumeration(this, findOneBinding(rbinding, false)); } else if (rbinding instanceof IFunction) { result = new CompositeCFunction(this, rbinding); } else if (rbinding instanceof IEnumerator) { result = new CompositeCEnumerator(this, rbinding); } else if (rbinding instanceof ITypedef) { result = new CompositeCTypedef(this, rbinding); } else if (rbinding instanceof IIndexMacroContainer) { result= new CompositeMacroContainer(this, rbinding); } else { throw new CompositingNotImplementedError("Composite binding unavailable for " + rbinding + " " + rbinding.getClass()); //$NON-NLS-1$ //$NON-NLS-2$ } return result; } }