001    /*
002     *  This file is part of the Jikes RVM project (http://jikesrvm.org).
003     *
004     *  This file is licensed to You under the Eclipse Public License (EPL);
005     *  You may not use this file except in compliance with the License. You
006     *  may obtain a copy of the License at
007     *
008     *      http://www.opensource.org/licenses/eclipse-1.0.php
009     *
010     *  See the COPYRIGHT.txt file distributed with this work for information
011     *  regarding copyright ownership.
012     */
013    package org.jikesrvm.compilers.opt.ir.operand;
014    
015    import org.jikesrvm.classloader.RVMType;
016    import org.jikesrvm.classloader.TypeReference;
017    
018    /**
019     * A TypeOperand represents a type.
020     * Used in checkcast, instanceof, new, etc.
021     * It will contain either a RVMType (if the type can be resolved
022     * at compile time) or a TypeReference (if the type cannot be resolved
023     * at compile time).
024     *
025     * @see Operand
026     * @see RVMType
027     * @see TypeReference
028     */
029    public final class TypeOperand extends Operand {
030    
031      /**
032       * A type
033       */
034      private final RVMType type;
035    
036      /**
037       * The data type.
038       */
039      private final TypeReference typeRef;
040    
041      /**
042       * Create a new type operand with the specified type.
043       */
044      public TypeOperand(RVMType typ) {
045        type = typ;
046        typeRef = type.getTypeRef();
047      }
048    
049      /**
050       * Create a new type operand with the specified type reference
051       */
052      public TypeOperand(TypeReference tr) {
053        type = tr.peekType();
054        typeRef = tr;
055      }
056    
057      private TypeOperand(RVMType t, TypeReference tr) {
058        type = t;
059        typeRef = tr;
060      }
061    
062      /**
063       * Return the {@link TypeReference} of the value represented by the operand.
064       *
065       * @return TypeReference.Type
066       */
067      public TypeReference getType() {
068        return TypeReference.Type;
069      }
070    
071      /**
072       * @return the TypeReference for this type operand
073       */
074      public TypeReference getTypeRef() {
075        return typeRef;
076      }
077    
078      /**
079       * @return the RVMType for this type operand -- may be null
080       */
081      public RVMType getVMType() {
082        if (type != null)
083          return type;
084        else
085          return typeRef.peekType();
086      }
087    
088      /**
089       * Return a new operand that is semantically equivalent to <code>this</code>.
090       *
091       * @return a copy of <code>this</code>
092       */
093      public Operand copy() {
094        return new TypeOperand(type, typeRef);
095      }
096    
097      /**
098       * Are two operands semantically equivalent?
099       *
100       * @param op other operand
101       * @return   <code>true</code> if <code>this</code> and <code>op</code>
102       *           are semantically equivalent or <code>false</code>
103       *           if they are not.
104       */
105      public boolean similar(Operand op) {
106        if (op instanceof TypeOperand) {
107          TypeOperand that = (TypeOperand) op;
108          return type == that.type && typeRef == that.typeRef;
109        } else {
110          return false;
111        }
112      }
113    
114      /**
115       * Returns the string representation of this operand.
116       *
117       * @return a string representation of this operand.
118       */
119      public String toString() {
120        if (type != null) {
121          return type.toString();
122        } else {
123          return typeRef.getName().toString();
124        }
125      }
126    }