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, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 * 23 */ 24 25package sun.jvm.hotspot.debugger.cdbg.basic; 26 27import java.util.*; 28import sun.jvm.hotspot.debugger.*; 29import sun.jvm.hotspot.debugger.cdbg.*; 30import sun.jvm.hotspot.utilities.Assert; 31 32public class BasicCompoundType extends BasicType implements CompoundType { 33 private CompoundTypeKind kind; 34 private List baseClasses; 35 private List fields; 36 37 public BasicCompoundType(String name, int size, CompoundTypeKind kind) { 38 this(name, size, kind, 0); 39 } 40 41 private BasicCompoundType(String name, int size, CompoundTypeKind kind, int cvAttributes) { 42 super(name, size, cvAttributes); 43 if (Assert.ASSERTS_ENABLED) { 44 Assert.that(kind != null, "null kind"); 45 } 46 this.kind = kind; 47 } 48 49 public CompoundType asCompound() { return this; } 50 51 public int getNumBaseClasses() { 52 return ((baseClasses == null) ? 0 : baseClasses.size()); 53 } 54 public BaseClass getBaseClass(int i) { 55 return (BaseClass) baseClasses.get(i); 56 } 57 58 public void addBaseClass(BaseClass b) { 59 if (baseClasses == null) { 60 baseClasses = new ArrayList(); 61 } 62 baseClasses.add(b); 63 } 64 65 public int getNumFields() { 66 return ((fields == null) ? 0 : fields.size()); 67 } 68 public Field getField(int i) { 69 return (Field) fields.get(i); 70 } 71 72 public void addField(Field f) { 73 if (fields == null) { 74 fields = new ArrayList(); 75 } 76 fields.add(f); 77 } 78 79 public boolean isClass() { return (kind == CompoundTypeKind.CLASS); } 80 public boolean isStruct() { return (kind == CompoundTypeKind.STRUCT); } 81 public boolean isUnion() { return (kind == CompoundTypeKind.UNION); } 82 83 Type resolveTypes(BasicCDebugInfoDataBase db, ResolveListener listener) { 84 super.resolveTypes(db, listener); 85 if (baseClasses != null) { 86 for (Iterator iter = baseClasses.iterator(); iter.hasNext(); ) { 87 BasicBaseClass b = (BasicBaseClass) iter.next(); 88 b.resolveTypes(this, db, listener); 89 } 90 } 91 if (fields != null) { 92 for (Iterator iter = fields.iterator(); iter.hasNext(); ) { 93 BasicField b = (BasicField) iter.next(); 94 b.resolveTypes(this, db, listener); 95 } 96 } 97 return this; 98 } 99 100 public void iterateObject(Address a, ObjectVisitor v, FieldIdentifier f) { 101 // What kind of iteration are we doing? If the end user requested 102 // iteration over a given object at a given address, the field 103 // identifier will be null, and we should descend and iterate over 104 // our fields and superclasses. Otherwise, we are already 105 // iterating through an object, and it is up to the end user 106 // whether to descend into the embedded object. 107 if (f == null) { 108 // FIXME: this is one of the key hard components of this 109 // implementation. Will need to properly handle multiple 110 // inheritance and possibly virtual base classes (i.e., not 111 // iterating twice for a virtual base class inherited indirectly 112 // more than once). For now, we do the simple thing, which 113 // assumes single inheritance. 114 for (int i = 0; i < getNumBaseClasses(); i++) { 115 BasicCompoundType b = (BasicCompoundType) getBaseClass(i).getType(); 116 b.iterateObject(a, v, f); 117 } 118 // Now we are in our scope 119 v.enterType(this, a); 120 // Iterate through our fields 121 for (int i = 0; i < getNumFields(); i++) { 122 Field field = getField(i); 123 BasicType fieldType = (BasicType) field.getType(); 124 fieldType.iterateObject(a.addOffsetTo(field.getOffset()), v, new BasicNamedFieldIdentifier(field)); 125 } 126 v.exitType(); 127 } else { 128 v.doCompound(f, a); 129 } 130 } 131 132 protected Type createCVVariant(int cvAttributes) { 133 BasicCompoundType t = new BasicCompoundType(getName(), getSize(), kind, cvAttributes); 134 t.kind = kind; 135 t.baseClasses = baseClasses; 136 t.fields = fields; 137 return t; 138 } 139 140 public void visit(TypeVisitor v) { 141 v.doCompoundType(this); 142 } 143} 144