/******************************************************************************* * Copyright (c) 2006, 2008 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: * IBM Corporation - initial API and implementation *******************************************************************************/ package org.eclipse.cdt.internal.core.dom.lrparser.c99.action.deprecated; import static org.eclipse.cdt.internal.core.dom.lrparser.c99.C99Parsersym.*; import java.util.HashMap; import java.util.Map; import org.eclipse.cdt.core.dom.ast.IBasicType; import org.eclipse.cdt.core.dom.ast.IType; import org.eclipse.cdt.core.dom.ast.c.ICBasicType; import org.eclipse.cdt.internal.core.dom.lrparser.c99.C99Parsersym; import org.eclipse.cdt.internal.core.dom.lrparser.c99.bindings.C99BasicType; import org.eclipse.cdt.internal.core.dom.lrparser.c99.bindings.C99Function; import org.eclipse.cdt.internal.core.dom.lrparser.c99.bindings.C99QualifierType; import org.eclipse.cdt.internal.core.dom.lrparser.c99.bindings.C99Variable; /** * Keeps track of declaration specifiers during the parse. * Used to compute types and determine if a declarator is a typedef. * * @author Mike Kucera */ class DeclSpec { // maps token kinds to the number of occurrences of that kind private Map<Integer,Integer> tokenKindMap = new HashMap<Integer,Integer>(); private IType type = null; public void add(int kind) { tokenKindMap.put(kind, count(kind) + 1); } public void remove(final int kind) { Integer count = tokenKindMap.get(kind); if(count == null) return; if(count <= 1) tokenKindMap.remove(kind); else tokenKindMap.put(kind, count - 1); } public boolean contains(int kind) { return tokenKindMap.containsKey(kind); } public boolean isTypedef() { return contains(C99Parsersym.TK_typedef); } /** * Need to keep track of how many times a particular * declaration specifier appears in order to support * long long. */ public int count(int kind) { Integer count = tokenKindMap.get(kind); return count == null ? 0 : count; } /** * Set if the type should be a structure. */ public void setType(IType type) { this.type = type; } public IType getType() { if(type != null) return type; if(tokenKindMap.isEmpty()) // there are no type tokens, so it must be implicit int return new C99BasicType(IBasicType.t_int); C99BasicType basicType = new C99BasicType(); for(int kind : tokenKindMap.keySet()) { switch(kind) { case TK_void: basicType.setType(IBasicType.t_void); break; case TK_char: basicType.setType(IBasicType.t_char); break; case TK_int: basicType.setType(IBasicType.t_int); break; case TK_float: basicType.setType(IBasicType.t_float); break; case TK_double: basicType.setType(IBasicType.t_double); break; case TK_long: boolean isLongLong = count(TK_long) > 1; basicType.setLongLong(isLongLong); basicType.setLong(!isLongLong); break; case TK_signed: basicType.setSigned(true); break; case TK_unsigned: basicType.setUnsigned(true); break; case TK_short: basicType.setShort(true); break; case TK__Bool: basicType.setType(ICBasicType.t_Bool); break; case TK__Complex: basicType.setComplex(true); break; case TK__Imaginary: basicType.setImaginary(true); break; } } boolean isConst = contains(TK_const); boolean isRestrict = contains(TK_restrict); boolean isVolatile = contains(TK_volatile); if(isConst || isRestrict || isVolatile) return new C99QualifierType(basicType, isConst, isVolatile, isRestrict); return basicType; } public void modifyBinding(C99Variable var) { if(!var.isAuto()) var.setAuto(contains(TK_auto)); if(!var.isExtern()) var.setExtern(contains(TK_extern)); if(!var.isRegister()) var.setRegister(contains(TK_register)); if(!var.isStatic()) var.setStatic(contains(TK_static)); } public void modifyBinding(C99Function function) { if(!function.isAuto()) function.setAuto(contains(TK_auto)); if(!function.isExtern()) function.setExtern(contains(TK_extern)); if(!function.isInline()) function.setInline(contains(TK_inline)); if(!function.isRegister()) function.setRegister(contains(TK_register)); if(!function.isStatic()) function.setStatic(contains(TK_static)); } }