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 }