/*
 * Copyright (c) 1999, 2014, Oracle and/or its affiliates. All rights reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.
 *
 * This code is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 * or visit www.oracle.com if you need additional information or have any
 * questions.
 *
 */

#ifndef SHARE_VM_C1_C1_VALUETYPE_HPP
#define SHARE_VM_C1_C1_VALUETYPE_HPP

#include "c1/c1_Compilation.hpp"
#include "ci/ciConstant.hpp"
#include "ci/ciMethodData.hpp"

// type hierarchy
class ValueType;
class   VoidType;
class   IntType;
class     IntConstant;
class     IntInterval;
class   LongType;
class     LongConstant;
class   FloatType;
class     FloatConstant;
class   DoubleType;
class     DoubleConstant;
class   ObjectType;
class     ObjectConstant;
class     ArrayType;
class       ArrayConstant;
class     InstanceType;
class       InstanceConstant;
class   MetadataType;
class     ClassType;
class       ClassConstant;
class     MethodType;
class       MethodConstant;
class     MethodDataType;
class       MethodDataConstant;
class   AddressType;
class     AddressConstant;
class   IllegalType;


// predefined types
extern VoidType*       voidType;
extern IntType*        intType;
extern LongType*       longType;
extern FloatType*      floatType;
extern DoubleType*     doubleType;
extern ObjectType*     objectType;
extern ArrayType*      arrayType;
extern InstanceType*   instanceType;
extern ClassType*      classType;
extern AddressType*    addressType;
extern IllegalType*    illegalType;


// predefined constants
extern IntConstant*    intZero;
extern IntConstant*    intOne;
extern ObjectConstant* objectNull;


// tags
enum ValueTag {
  // all legal tags must come first
  intTag,
  longTag,
  floatTag,
  doubleTag,
  objectTag,
  addressTag,
  metaDataTag,
  number_of_legal_tags,
  // all other tags must follow afterwards
  voidTag = number_of_legal_tags,
  illegalTag,
  number_of_tags
};


class ValueType: public CompilationResourceObj {
 private:
  const int _size;
  const ValueTag _tag;
  ValueType();
 protected:
  ValueType(ValueTag tag, int size): _tag(tag), _size(size) {}

 public:
  // initialization
  static void initialize(Arena* arena);

  // accessors
  virtual ValueType* base() const                = 0; // the 'canonical' type (e.g., intType for an IntConstant)
  ValueTag tag() const { return _tag; }          // the 'canonical' tag  (useful for type matching)
  int size() const {                             // the size of an object of the type in words
    assert(_size > -1, "shouldn't be asking for size");
    return _size;
  }
  virtual const char tchar() const               = 0; // the type 'character' for printing
  virtual const char* name() const               = 0; // the type name for printing
  virtual bool is_constant() const               { return false; }

  // testers
  bool is_void()                                 { return tag() == voidTag;   }
  bool is_int()                                  { return tag() == intTag;    }
  bool is_long()                                 { return tag() == longTag;   }
  bool is_float()                                { return tag() == floatTag;  }
  bool is_double()                               { return tag() == doubleTag; }
  bool is_object()                               { return as_ObjectType()   != NULL; }
  bool is_array()                                { return as_ArrayType()    != NULL; }
  bool is_instance()                             { return as_InstanceType() != NULL; }
  bool is_class()                                { return as_ClassType()    != NULL; }
  bool is_method()                               { return as_MethodType()   != NULL; }
  bool is_method_data()                          { return as_MethodDataType() != NULL; }
  bool is_address()                              { return as_AddressType()  != NULL; }
  bool is_illegal()                              { return tag() == illegalTag; }

  bool is_int_kind() const                       { return tag() == intTag || tag() == longTag; }
  bool is_float_kind() const                     { return tag() == floatTag || tag() == doubleTag; }
  bool is_object_kind() const                    { return tag() == objectTag; }

  bool is_single_word() const                    { return _size == 1; }
  bool is_double_word() const                    { return _size == 2; }

  // casting
  virtual VoidType*         as_VoidType()        { return NULL; }
  virtual IntType*          as_IntType()         { return NULL; }
  virtual LongType*         as_LongType()        { return NULL; }
  virtual FloatType*        as_FloatType()       { return NULL; }
  virtual DoubleType*       as_DoubleType()      { return NULL; }
  virtual ObjectType*       as_ObjectType()      { return NULL; }
  virtual ArrayType*        as_ArrayType()       { return NULL; }
  virtual InstanceType*     as_InstanceType()    { return NULL; }
  virtual ClassType*        as_ClassType()       { return NULL; }
  virtual MetadataType*     as_MetadataType()    { return NULL; }
  virtual MethodType*       as_MethodType()      { return NULL; }
  virtual MethodDataType*   as_MethodDataType()  { return NULL; }
  virtual AddressType*      as_AddressType()     { return NULL; }
  virtual IllegalType*      as_IllegalType()     { return NULL; }

  virtual IntConstant*      as_IntConstant()     { return NULL; }
  virtual LongConstant*     as_LongConstant()    { return NULL; }
  virtual FloatConstant*    as_FloatConstant()   { return NULL; }
  virtual DoubleConstant*   as_DoubleConstant()  { return NULL; }
  virtual ObjectConstant*   as_ObjectConstant()  { return NULL; }
  virtual InstanceConstant* as_InstanceConstant(){ return NULL; }
  virtual ClassConstant*    as_ClassConstant()   { return NULL; }
  virtual MethodConstant*   as_MethodConstant()  { return NULL; }
  virtual MethodDataConstant* as_MethodDataConstant() { return NULL; }
  virtual ArrayConstant*    as_ArrayConstant()   { return NULL; }
  virtual AddressConstant*  as_AddressConstant() { return NULL; }

  // type operations
  ValueType* meet(ValueType* y) const;
  ValueType* join(ValueType* y) const;

  // debugging
  void print(outputStream* s = tty)              { s->print("%s", name()); }
};


class VoidType: public ValueType {
 public:
  VoidType(): ValueType(voidTag, 0) {}
  virtual ValueType* base() const                { return voidType; }
  virtual const char tchar() const               { return 'v'; }
  virtual const char* name() const               { return "void"; }
  virtual VoidType* as_VoidType()                { return this; }
};


class IntType: public ValueType {
 public:
  IntType(): ValueType(intTag, 1) {}
  virtual ValueType* base() const                { return intType; }
  virtual const char tchar() const               { return 'i'; }
  virtual const char* name() const               { return "int"; }
  virtual IntType* as_IntType()                  { return this; }
};


class IntConstant: public IntType {
 private:
  jint _value;

 public:
  IntConstant(jint value)                        { _value = value; }

  jint value() const                             { return _value; }

  virtual bool is_constant() const               { return true; }
  virtual IntConstant* as_IntConstant()          { return this; }
};


class IntInterval: public IntType {
 private:
  jint _beg;
  jint _end;

 public:
  IntInterval(jint beg, jint end) {
    assert(beg <= end, "illegal interval");
    _beg = beg;
    _end = end;
  }

  jint beg() const                               { return _beg; }
  jint end() const                               { return _end; }

  virtual bool is_interval() const               { return true; }
};


class LongType: public ValueType {
 public:
  LongType(): ValueType(longTag, 2) {}
  virtual ValueType* base() const                { return longType; }
  virtual const char tchar() const               { return 'l'; }
  virtual const char* name() const               { return "long"; }
  virtual LongType* as_LongType()                { return this; }
};


class LongConstant: public LongType {
 private:
  jlong _value;

 public:
  LongConstant(jlong value)                      { _value = value; }

  jlong value() const                            { return _value; }

  virtual bool is_constant() const               { return true; }
  virtual LongConstant* as_LongConstant()        { return this; }
};


class FloatType: public ValueType {
 public:
  FloatType(): ValueType(floatTag, 1) {}
  virtual ValueType* base() const                { return floatType; }
  virtual const char tchar() const               { return 'f'; }
  virtual const char* name() const               { return "float"; }
  virtual FloatType* as_FloatType()              { return this; }
};


class FloatConstant: public FloatType {
 private:
  jfloat _value;

 public:
  FloatConstant(jfloat value)                    { _value = value; }

  jfloat value() const                           { return _value; }

  virtual bool is_constant() const               { return true; }
  virtual FloatConstant* as_FloatConstant()      { return this; }
};


class DoubleType: public ValueType {
 public:
  DoubleType(): ValueType(doubleTag, 2) {}
  virtual ValueType* base() const                { return doubleType; }
  virtual const char tchar() const               { return 'd'; }
  virtual const char* name() const               { return "double"; }
  virtual DoubleType* as_DoubleType()            { return this; }
};


class DoubleConstant: public DoubleType {
 private:
  jdouble _value;

 public:
  DoubleConstant(jdouble value)                  { _value = value; }

  jdouble value() const                          { return _value; }

  virtual bool is_constant() const               { return true; }
  virtual DoubleConstant* as_DoubleConstant()    { return this; }
};


class ObjectType: public ValueType {
 public:
  ObjectType(): ValueType(objectTag, 1) {}
  virtual ValueType* base() const                { return objectType; }
  virtual const char tchar() const               { return 'a'; }
  virtual const char* name() const               { return "object"; }
  virtual ObjectType* as_ObjectType()            { return this; }
  virtual ciObject* constant_value() const       { ShouldNotReachHere(); return NULL; }
  virtual ciType* exact_type() const             { return NULL; }
  bool is_loaded() const;
  jobject encoding() const;
};


class ObjectConstant: public ObjectType {
 private:
  ciObject* _value;

 public:
  ObjectConstant(ciObject* value)                { _value = value; }

  ciObject* value() const                        { return _value; }

  virtual bool is_constant() const               { return true; }
  virtual ObjectConstant* as_ObjectConstant()    { return this; }
  virtual ciObject* constant_value() const;
  virtual ciType* exact_type() const;
};


class ArrayType: public ObjectType {
 public:
  virtual ArrayType* as_ArrayType()              { return this; }
};


class ArrayConstant: public ArrayType {
 private:
  ciArray* _value;

 public:
  ArrayConstant(ciArray* value)                  { _value = value; }

  ciArray* value() const                         { return _value; }

  virtual bool is_constant() const               { return true; }
  virtual ArrayConstant* as_ArrayConstant()      { return this; }
  virtual ciObject* constant_value() const;
  virtual ciType* exact_type() const;
};


class InstanceType: public ObjectType {
 public:
  virtual InstanceType* as_InstanceType()        { return this; }
};


class InstanceConstant: public InstanceType {
 private:
  ciInstance* _value;

 public:
  InstanceConstant(ciInstance* value)            { _value = value; }

  ciInstance* value() const                      { return _value; }

  virtual bool is_constant() const               { return true; }
  virtual InstanceConstant* as_InstanceConstant(){ return this; }
  virtual ciObject* constant_value() const;
  virtual ciType* exact_type() const;
};


class MetadataType: public ValueType {
 public:
  MetadataType(): ValueType(metaDataTag, 1) {}
  virtual ValueType* base() const                       { return objectType; }
  virtual const char tchar() const                      { return 'a'; }
  virtual const char* name() const                      { return "object"; }
  virtual MetadataType* as_MetadataType()               { return this; }
  bool is_loaded() const;
  jobject encoding() const;
  virtual ciMetadata* constant_value() const            { ShouldNotReachHere(); return NULL;  }
};


class ClassType: public MetadataType {
 public:
  virtual ClassType* as_ClassType()              { return this; }
};


class ClassConstant: public ClassType {
 private:
  ciInstanceKlass* _value;

 public:
  ClassConstant(ciInstanceKlass* value)          { _value = value; }

  ciInstanceKlass* value() const                 { return _value; }

  virtual bool is_constant() const               { return true; }
  virtual ClassConstant* as_ClassConstant()      { return this; }
  virtual ciMetadata* constant_value() const            { return _value; }
  virtual ciType* exact_type() const;
};


class MethodType: public MetadataType {
 public:
  virtual MethodType* as_MethodType()                   { return this; }
};


class MethodConstant: public MethodType {
 private:
  ciMethod* _value;

 public:
  MethodConstant(ciMethod* value)                       { _value = value; }

  ciMethod* value() const                               { return _value; }

  virtual bool is_constant() const                      { return true; }

  virtual MethodConstant* as_MethodConstant()           { return this; }
  virtual ciMetadata* constant_value() const            { return _value; }
};


class MethodDataType: public MetadataType {
 public:
  virtual MethodDataType* as_MethodDataType()           { return this; }
};


class MethodDataConstant: public MethodDataType {
 private:
  ciMethodData* _value;

 public:
  MethodDataConstant(ciMethodData* value)               { _value = value; }

  ciMethodData* value() const                           { return _value; }

  virtual bool is_constant() const                      { return true; }

  virtual MethodDataConstant* as_MethodDataConstant()   { return this; }
  virtual ciMetadata* constant_value() const            { return _value; }
};


class AddressType: public ValueType {
 public:
  AddressType(): ValueType(addressTag, 1) {}
  virtual ValueType* base() const                { return addressType; }
  virtual const char tchar() const               { return 'r'; }
  virtual const char* name() const               { return "address"; }
  virtual AddressType* as_AddressType()          { return this; }
};


class AddressConstant: public AddressType {
 private:
  jint _value;

 public:
  AddressConstant(jint value)                    { _value = value; }

  jint value() const                             { return _value; }

  virtual bool is_constant() const               { return true; }

  virtual AddressConstant* as_AddressConstant()  { return this; }
};


class IllegalType: public ValueType {
 public:
  IllegalType(): ValueType(illegalTag, -1) {}
  virtual ValueType* base() const                { return illegalType; }
  virtual const char tchar() const               { return ' '; }
  virtual const char* name() const               { return "illegal"; }
  virtual IllegalType* as_IllegalType()          { return this; }
};


// conversion between ValueTypes, BasicTypes, and ciConstants
ValueType* as_ValueType(BasicType type);
ValueType* as_ValueType(ciConstant value);
BasicType  as_BasicType(ValueType* type);

inline ValueType* as_ValueType(ciType* type) { return as_ValueType(type->basic_type()); }

#endif // SHARE_VM_C1_C1_VALUETYPE_HPP
