/******************************************************************************* * Copyright (c) 2004, 2013 IBM Corporation 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 Niefer (IBM Corporation) - initial API and implementation * Markus Schorn (Wind River Systems) * Nathan Ridge *******************************************************************************/ package org.eclipse.cdt.internal.core.dom.parser.c; import org.eclipse.cdt.core.dom.ILinkage; import org.eclipse.cdt.core.dom.ast.ASTNodeProperty; import org.eclipse.cdt.core.dom.ast.IASTDeclSpecifier; import org.eclipse.cdt.core.dom.ast.IASTElaboratedTypeSpecifier; import org.eclipse.cdt.core.dom.ast.IASTEnumerationSpecifier; 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.IEnumeration; import org.eclipse.cdt.core.dom.ast.IEnumerator; import org.eclipse.cdt.core.dom.ast.IProblemBinding; 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.c.ICASTElaboratedTypeSpecifier; import org.eclipse.cdt.core.dom.ast.c.ICASTEnumerationSpecifier; import org.eclipse.cdt.core.index.IIndexBinding; import org.eclipse.cdt.internal.core.dom.Linkage; import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil; import org.eclipse.core.runtime.PlatformObject; /** * Binding for enumerations in C. */ public class CEnumeration extends PlatformObject implements IEnumeration, ICInternalBinding { private IASTName[] declarations = null; private IASTName definition = null; private Long fMinValue; private Long fMaxValue; public CEnumeration(IASTName enumeration) { ASTNodeProperty prop = enumeration.getPropertyInParent(); if (prop == IASTElaboratedTypeSpecifier.TYPE_NAME) declarations = new IASTName[] { enumeration }; else definition = enumeration; enumeration.setBinding(this); } public void addDeclaration(IASTName decl) { if (!decl.isActive()) return; if (decl.getPropertyInParent() != IASTElaboratedTypeSpecifier.TYPE_NAME) return; decl.setBinding(this); if (declarations == null) { declarations = new IASTName[] { decl }; return; } for (int i = 0; i < declarations.length; i++) { if (declarations[i] == null) { declarations[i] = decl; return; } } IASTName tmp[] = new IASTName[declarations.length * 2]; System.arraycopy(declarations, 0, tmp, 0, declarations.length); tmp[declarations.length] = decl; declarations = tmp; } @Override public IASTNode getPhysicalNode() { if (definition != null) return definition; return declarations[0]; } private void checkForDefinition() { IASTDeclSpecifier spec = CVisitor.findDefinition((ICASTElaboratedTypeSpecifier) declarations[0].getParent()); if (spec != null && spec instanceof ICASTEnumerationSpecifier) { ICASTEnumerationSpecifier enumSpec = (ICASTEnumerationSpecifier) spec; enumSpec.getName().setBinding(this); definition = enumSpec.getName(); } return; } /* (non-Javadoc) * @see org.eclipse.cdt.core.dom.ast.IBinding#getName() */ @Override public String getName() { if (definition != null) return definition.toString(); return declarations[0].toString(); } @Override public char[] getNameCharArray() { if (definition != null) return definition.toCharArray(); return declarations[0].toCharArray(); } /* (non-Javadoc) * @see org.eclipse.cdt.core.dom.ast.IBinding#getScope() */ @Override public IScope getScope() { return CVisitor.getContainingScope(definition != null ? definition : declarations[0].getParent()); } @Override public Object clone() { IType t = null; try { t = (IType) super.clone(); } catch (CloneNotSupportedException e) { //not going to happen } return t; } /* (non-Javadoc) * @see org.eclipse.cdt.core.dom.ast.IEnumeration#getEnumerators() */ @Override public IEnumerator[] getEnumerators() { if (definition == null) { checkForDefinition(); if (definition == null) return new IEnumerator[] { new CEnumerator.CEnumeratorProblem(declarations[0], IProblemBinding.SEMANTIC_DEFINITION_NOT_FOUND, declarations[0].toCharArray()) }; } IASTEnumerationSpecifier enumSpec = (IASTEnumerationSpecifier) definition.getParent(); IASTEnumerationSpecifier.IASTEnumerator[] enums = enumSpec.getEnumerators(); IEnumerator[] bindings = new IEnumerator[enums.length]; for (int i = 0; i < enums.length; i++) { bindings[i] = (IEnumerator) enums[i].getName().resolveBinding(); } return bindings; } public void addDefinition(IASTName name) { if (name.isActive()) definition = name; } /* (non-Javadoc) * @see org.eclipse.cdt.core.dom.ast.IType#isSameType(org.eclipse.cdt.core.dom.ast.IType) */ @Override public boolean isSameType(IType type) { if (type == this) return true; if (type instanceof ITypedef || type instanceof IIndexBinding) return type.isSameType(this); return false; } @Override public ILinkage getLinkage() { return Linkage.C_LINKAGE; } @Override public IASTNode[] getDeclarations() { return declarations; } @Override public IASTNode getDefinition() { return definition; } @Override public IBinding getOwner() { IASTNode node= definition; if (node == null && declarations != null && declarations.length > 0) { node= declarations[0]; } // either local or global, never part of structs return CVisitor.findEnclosingFunction(node); } @Override public String toString() { return getName(); } @Override public long getMinValue() { if (fMinValue != null) return fMinValue.longValue(); long minValue = SemanticUtil.computeMinValue(this); fMinValue= minValue; return minValue; } @Override public long getMaxValue() { if (fMaxValue != null) return fMaxValue.longValue(); long maxValue = SemanticUtil.computeMaxValue(this); fMaxValue= maxValue; return maxValue; } }