1 /*
   2  * Copyright (c) 2001, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.
   8  *
   9  * This code is distributed in the hope that it will be useful, but WITHOUT
  10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  12  * version 2 for more details (a copy is included in the LICENSE file that
  13  * accompanied this code).
  14  *
  15  * You should have received a copy of the GNU General Public License version
  16  * 2 along with this work; if not, write to the Free Software Foundation,
  17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  18  *
  19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores,
  20  * CA 94065 USA or visit www.oracle.com if you need additional information or
  21  * have any questions.
  22  *
  23  */
  24 
  25 package sun.jvm.hotspot.debugger.cdbg.basic;
  26 
  27 import java.util.*;
  28 import sun.jvm.hotspot.debugger.*;
  29 import sun.jvm.hotspot.debugger.cdbg.*;
  30 import sun.jvm.hotspot.utilities.Assert;
  31 
  32 public class BasicEnumType extends BasicIntType implements EnumType {
  33   // Integer type or lazy type
  34   private Type underlyingType;
  35 
  36   private static class Enum {
  37     String name;
  38     long   value;
  39     Enum(String name, long value) {
  40       this.name = name;
  41       this.value = value;
  42     }
  43 
  44     String getName()  { return name; }
  45     long   getValue() { return value; }
  46   }
  47   private List/*<Enum>*/ enums;
  48 
  49   /** Underlying type of enum must be an integer type (or as yet
  50       unresolved) */
  51 
  52   public BasicEnumType(String name, Type underlyingType) {
  53     this(name, underlyingType, 0);
  54   }
  55 
  56   private BasicEnumType(String name, Type underlyingType, int cvAttributes) {
  57     super(name, 0, false, cvAttributes);
  58     this.underlyingType = underlyingType;
  59   }
  60 
  61   public EnumType asEnum()    { return this; }
  62 
  63   public int     getSize() { return underlyingType.getSize(); }
  64   public boolean isUnsigned() {
  65     if (underlyingType.isInt()) {
  66       return ((IntType) underlyingType).isUnsigned();
  67     }
  68     return false;
  69   }
  70 
  71   public void addEnum(String name, long val) {
  72     if (enums == null) {
  73       enums = new ArrayList();
  74     }
  75     enums.add(new Enum(name, val));
  76   }
  77 
  78   public int    getNumEnumerates()  { return enums.size(); }
  79   public String getEnumName(int i)  { return ((Enum) enums.get(i)).getName();  }
  80   public long   getEnumValue(int i) { return ((Enum) enums.get(i)).getValue(); }
  81 
  82   public String enumNameForValue(long val) {
  83     if (enums == null) {
  84       return null;
  85     }
  86 
  87     for (Iterator iter = enums.iterator(); iter.hasNext(); ) {
  88       Enum e = (Enum) iter.next();
  89       if (e.getValue() == val) {
  90         return e.getName();
  91       }
  92     }
  93 
  94     return null;
  95   }
  96 
  97   Type resolveTypes(BasicCDebugInfoDataBase db, ResolveListener listener) {
  98     super.resolveTypes(db, listener);
  99     underlyingType = db.resolveType(this, underlyingType, listener, "resolving enum type");
 100     if (Assert.ASSERTS_ENABLED) {
 101       BasicType b = (BasicType) underlyingType;
 102       Assert.that(b.isLazy() || b.isInt(),
 103                   "Underlying type of enum must be integer type (or unresolved due to error)");
 104     }
 105     return this;
 106   }
 107 
 108   public void iterateObject(Address a, ObjectVisitor v, FieldIdentifier f) {
 109     long val = a.getCIntegerAt(0, getSize(), isUnsigned());
 110     v.doEnum(f, val, enumNameForValue(val));
 111   }
 112 
 113   protected Type createCVVariant(int cvAttributes) {
 114     BasicEnumType t = new BasicEnumType(getName(), underlyingType, cvAttributes);
 115     t.enums = enums;
 116     return t;
 117   }
 118 
 119   public void visit(TypeVisitor v) {
 120     v.doEnumType(this);
 121   }
 122 }