ROOT logo
/* /% C++ %/ */
/***********************************************************************
 * cint (C/C++ interpreter)
 ************************************************************************
 * Source file Type.cxx
 ************************************************************************
 * Description:
 *  Extended Run Time Type Identification API
 ************************************************************************
 * Author                  Masaharu Goto
 * Copyright(c) 1995~2005  Masaharu Goto
 *
 * For the licensing terms see the file COPYING
 *
 ************************************************************************/

#include "Api.h"
#include "Dict.h"
#include "common.h"
#include "fproto.h"

using namespace Cint::Internal;
using namespace std;

//______________________________________________________________________________
static char G__buf[G__LONGLINE]; // This length should match or exceed the length in G__type2string

//______________________________________________________________________________
Cint::G__TypeInfo::~G__TypeInfo()
{
}

#if 0
//______________________________________________________________________________
Cint::G__TypeInfo::G__TypeInfo(const ::Reflex::Type in) : G__ClassInfo()
{
   Init(in);
}
#endif // 0

//______________________________________________________________________________
Cint::G__TypeInfo::G__TypeInfo(const char* typenamein) : G__ClassInfo(), fType(0), fTypenum(-1), fReftype(0), fIsconst(0)
{
   Init(typenamein);
}

//______________________________________________________________________________
Cint::G__TypeInfo::G__TypeInfo() : G__ClassInfo(), fType(0), fTypenum(-1), fReftype(0), fIsconst(0)
{
}

//______________________________________________________________________________
void Cint::G__TypeInfo::Init(const char* typenamein)
{
   G__value buf = G__string2type_body(typenamein, 2);
   ::Reflex::Type ty = G__value_typenum(buf);
   // G__ClassInfo part.
   fClassProperty = 0;
   // G__TypeInfo part.
   G__get_cint5_type_tuple_long(ty, &fType, &fTagnum, &fTypenum, &fReftype, &fIsconst);
   fIsconst = buf.obj.i;
}

#if 0
//______________________________________________________________________________
void Cint::G__TypeInfo::Init(const ::Reflex::Type in)
{
   // G__ClassInfo part.
   fTagnum = G__get_tagnum(fTypenum);
   class_property = 0;
   // G__TypeInfo part.
   fTypenum = in;
}
#endif // 0

//______________________________________________________________________________
Cint::G__TypeInfo::G__TypeInfo(G__value buf) : G__ClassInfo(), fType(0), fTypenum(-1), fReftype(0), fIsconst(0)
{
   Init(buf);
}

//______________________________________________________________________________
void Cint::G__TypeInfo::Init(G__value& buf)
{
   ::Reflex::Type ty = G__value_typenum(buf);
   G__get_cint5_type_tuple_long(ty, &fType, &fTagnum, &fTypenum, &fReftype, &fIsconst);
   if ((fType == 'd') || (fType == 'f')) {
      fReftype = 0;
   }
}

//______________________________________________________________________________
void Cint::G__TypeInfo::Init(G__var_array* var, int idx)
{
   ::Reflex::Member m = G__Dict::GetDict().GetDataMember(var, idx);
   ::Reflex::Type ty = m.TypeOf();
   G__get_cint5_type_tuple_long(ty, &fType, &fTagnum, &fTypenum, &fReftype, &fIsconst);
}

//______________________________________________________________________________
Cint::G__TypeInfo::G__TypeInfo(const G__TypeInfo& rhs) : G__ClassInfo(rhs), fType(rhs.fType), fTypenum(rhs.fTypenum), fReftype(rhs.fReftype), fIsconst(rhs.fIsconst)
{
}

//______________________________________________________________________________
G__TypeInfo& Cint::G__TypeInfo::operator=(const G__TypeInfo& rhs)
{
   if (this != &rhs) {
      fType = rhs.fType;
      fTypenum = rhs.fTypenum;
      fReftype = rhs.fReftype;
      fIsconst = rhs.fIsconst;
   }
   return *this;
}

//______________________________________________________________________________
int Cint::G__TypeInfo::operator==(const G__TypeInfo& a)
{
   if ((fType == a.fType) && (fTagnum == a.fTagnum) && (fTypenum == a.fTypenum) && (fReftype == a.fReftype)) {
      return 1;
   }
   return 0;
}

//______________________________________________________________________________
int Cint::G__TypeInfo::operator!=(const G__TypeInfo& a)
{
   return !this->operator==(a);
}

//______________________________________________________________________________
const char* Cint::G__TypeInfo::Name()
{
   strcpy(G__buf, G__type2string((int) fType, (int) fTagnum, (int) fTypenum, (int) fReftype, (int) fIsconst));
   return G__buf;
}

//______________________________________________________________________________
const char* Cint::G__TypeInfo::TrueName()
{
   strcpy(G__buf, G__type2string((int) fType, (int) fTagnum, -1, (int) fReftype, (int) fIsconst));
   return G__buf;
}

//______________________________________________________________________________
int Cint::G__TypeInfo::Size() const
{
   G__value buf;
   ::Reflex::Type ty = G__cint5_tuple_to_type((int) fType, (int) fTagnum, (int) fTypenum, (int) fReftype, 0);
   G__value_typenum(buf) = ty;
   buf.ref = fReftype;
   if (isupper(fType)) {
      return sizeof(void*);
   }
   return G__sizeof(&buf);
}

//______________________________________________________________________________
long Cint::G__TypeInfo::Property()
{
   long property = 0L;
   if (fTypenum != -1L) {
      property |= G__BIT_ISTYPEDEF;
   }
   if (fTagnum == -1L) {
      property |= G__BIT_ISFUNDAMENTAL;
   }
   else {
      std::string cname = G__Dict::GetDict().GetScope(fTagnum).Name();
      if (
         (cname == "G__longlong") ||
         (cname == "G__ulonglong") ||
         (cname == "G__longdouble")
      ) {
         property |= G__BIT_ISFUNDAMENTAL;
         if (fTypenum != -1L) {
            std::string tname = G__Dict::GetDict().GetTypedef(fTypenum).Name();
            if (
               (tname == "long long") ||
               (tname == "unsigned long long") ||
               (tname == "long double")
            ) {
               property &= (~G__BIT_ISTYPEDEF);
            }
         }
      }
      else {
         if (G__ClassInfo::IsValid()) {
            property |= G__ClassInfo::Property();
         }
      }
   }
   if (isupper((int) fType)) {
      property |= G__BIT_ISPOINTER;
   }
   if ((fReftype == G__PARAREFERENCE) || (fReftype > G__PARAREF)) {
      property |= G__BIT_ISREFERENCE;
   }
   if (fIsconst & G__CONSTVAR) {
      property |= G__BIT_ISCONSTANT;
   }
   if (fIsconst & G__PCONSTVAR) {
      property |= G__BIT_ISPCONSTANT;
   }
   return property;
}

//______________________________________________________________________________
int Cint::G__TypeInfo::IsValid()
{
   if (G__ClassInfo::IsValid()) {
      return 1;
   }
   else if (fType) {
      return 1;
   }
   return 0;
}

//______________________________________________________________________________
void* Cint::G__TypeInfo::New()
{
   if (G__ClassInfo::IsValid()) {
      return G__ClassInfo::New();
   }
   size_t size = Size();
   void* p = new char[size];
   return p;
}

//______________________________________________________________________________
int Cint::G__TypeInfo::Typenum() const
{
   return fTypenum;
}

//______________________________________________________________________________
int Cint::G__TypeInfo::Type() const
{
   return fType;
}

//______________________________________________________________________________
int Cint::G__TypeInfo::Reftype() const
{
   return fReftype;
}

//______________________________________________________________________________
int Cint::G__TypeInfo::Isconst() const
{
   return fIsconst;
}

#if 0
//______________________________________________________________________________
Reflex::Type Cint::G__TypeInfo::ReflexType() const
{
   return fTypenum;
}
#endif // 0

//______________________________________________________________________________
G__value Cint::G__TypeInfo::Value() const
{
   G__value buf;
   ::Reflex::Type ty = G__cint5_tuple_to_type((int) fType, (int) fTagnum, (int) fTypenum, (int) fReftype, (int) fIsconst);
   G__value_typenum(buf) = ty;
   buf.obj.i = 1;
   buf.ref = 0;
   return buf;
}

//______________________________________________________________________________
int Cint::G__TypeInfo::Next()
{
   return 0;
}

 Type.cxx:1
 Type.cxx:2
 Type.cxx:3
 Type.cxx:4
 Type.cxx:5
 Type.cxx:6
 Type.cxx:7
 Type.cxx:8
 Type.cxx:9
 Type.cxx:10
 Type.cxx:11
 Type.cxx:12
 Type.cxx:13
 Type.cxx:14
 Type.cxx:15
 Type.cxx:16
 Type.cxx:17
 Type.cxx:18
 Type.cxx:19
 Type.cxx:20
 Type.cxx:21
 Type.cxx:22
 Type.cxx:23
 Type.cxx:24
 Type.cxx:25
 Type.cxx:26
 Type.cxx:27
 Type.cxx:28
 Type.cxx:29
 Type.cxx:30
 Type.cxx:31
 Type.cxx:32
 Type.cxx:33
 Type.cxx:34
 Type.cxx:35
 Type.cxx:36
 Type.cxx:37
 Type.cxx:38
 Type.cxx:39
 Type.cxx:40
 Type.cxx:41
 Type.cxx:42
 Type.cxx:43
 Type.cxx:44
 Type.cxx:45
 Type.cxx:46
 Type.cxx:47
 Type.cxx:48
 Type.cxx:49
 Type.cxx:50
 Type.cxx:51
 Type.cxx:52
 Type.cxx:53
 Type.cxx:54
 Type.cxx:55
 Type.cxx:56
 Type.cxx:57
 Type.cxx:58
 Type.cxx:59
 Type.cxx:60
 Type.cxx:61
 Type.cxx:62
 Type.cxx:63
 Type.cxx:64
 Type.cxx:65
 Type.cxx:66
 Type.cxx:67
 Type.cxx:68
 Type.cxx:69
 Type.cxx:70
 Type.cxx:71
 Type.cxx:72
 Type.cxx:73
 Type.cxx:74
 Type.cxx:75
 Type.cxx:76
 Type.cxx:77
 Type.cxx:78
 Type.cxx:79
 Type.cxx:80
 Type.cxx:81
 Type.cxx:82
 Type.cxx:83
 Type.cxx:84
 Type.cxx:85
 Type.cxx:86
 Type.cxx:87
 Type.cxx:88
 Type.cxx:89
 Type.cxx:90
 Type.cxx:91
 Type.cxx:92
 Type.cxx:93
 Type.cxx:94
 Type.cxx:95
 Type.cxx:96
 Type.cxx:97
 Type.cxx:98
 Type.cxx:99
 Type.cxx:100
 Type.cxx:101
 Type.cxx:102
 Type.cxx:103
 Type.cxx:104
 Type.cxx:105
 Type.cxx:106
 Type.cxx:107
 Type.cxx:108
 Type.cxx:109
 Type.cxx:110
 Type.cxx:111
 Type.cxx:112
 Type.cxx:113
 Type.cxx:114
 Type.cxx:115
 Type.cxx:116
 Type.cxx:117
 Type.cxx:118
 Type.cxx:119
 Type.cxx:120
 Type.cxx:121
 Type.cxx:122
 Type.cxx:123
 Type.cxx:124
 Type.cxx:125
 Type.cxx:126
 Type.cxx:127
 Type.cxx:128
 Type.cxx:129
 Type.cxx:130
 Type.cxx:131
 Type.cxx:132
 Type.cxx:133
 Type.cxx:134
 Type.cxx:135
 Type.cxx:136
 Type.cxx:137
 Type.cxx:138
 Type.cxx:139
 Type.cxx:140
 Type.cxx:141
 Type.cxx:142
 Type.cxx:143
 Type.cxx:144
 Type.cxx:145
 Type.cxx:146
 Type.cxx:147
 Type.cxx:148
 Type.cxx:149
 Type.cxx:150
 Type.cxx:151
 Type.cxx:152
 Type.cxx:153
 Type.cxx:154
 Type.cxx:155
 Type.cxx:156
 Type.cxx:157
 Type.cxx:158
 Type.cxx:159
 Type.cxx:160
 Type.cxx:161
 Type.cxx:162
 Type.cxx:163
 Type.cxx:164
 Type.cxx:165
 Type.cxx:166
 Type.cxx:167
 Type.cxx:168
 Type.cxx:169
 Type.cxx:170
 Type.cxx:171
 Type.cxx:172
 Type.cxx:173
 Type.cxx:174
 Type.cxx:175
 Type.cxx:176
 Type.cxx:177
 Type.cxx:178
 Type.cxx:179
 Type.cxx:180
 Type.cxx:181
 Type.cxx:182
 Type.cxx:183
 Type.cxx:184
 Type.cxx:185
 Type.cxx:186
 Type.cxx:187
 Type.cxx:188
 Type.cxx:189
 Type.cxx:190
 Type.cxx:191
 Type.cxx:192
 Type.cxx:193
 Type.cxx:194
 Type.cxx:195
 Type.cxx:196
 Type.cxx:197
 Type.cxx:198
 Type.cxx:199
 Type.cxx:200
 Type.cxx:201
 Type.cxx:202
 Type.cxx:203
 Type.cxx:204
 Type.cxx:205
 Type.cxx:206
 Type.cxx:207
 Type.cxx:208
 Type.cxx:209
 Type.cxx:210
 Type.cxx:211
 Type.cxx:212
 Type.cxx:213
 Type.cxx:214
 Type.cxx:215
 Type.cxx:216
 Type.cxx:217
 Type.cxx:218
 Type.cxx:219
 Type.cxx:220
 Type.cxx:221
 Type.cxx:222
 Type.cxx:223
 Type.cxx:224
 Type.cxx:225
 Type.cxx:226
 Type.cxx:227
 Type.cxx:228
 Type.cxx:229
 Type.cxx:230
 Type.cxx:231
 Type.cxx:232
 Type.cxx:233
 Type.cxx:234
 Type.cxx:235
 Type.cxx:236
 Type.cxx:237
 Type.cxx:238
 Type.cxx:239
 Type.cxx:240
 Type.cxx:241
 Type.cxx:242
 Type.cxx:243
 Type.cxx:244
 Type.cxx:245
 Type.cxx:246
 Type.cxx:247
 Type.cxx:248
 Type.cxx:249
 Type.cxx:250
 Type.cxx:251
 Type.cxx:252
 Type.cxx:253
 Type.cxx:254
 Type.cxx:255
 Type.cxx:256
 Type.cxx:257
 Type.cxx:258
 Type.cxx:259
 Type.cxx:260
 Type.cxx:261
 Type.cxx:262
 Type.cxx:263
 Type.cxx:264
 Type.cxx:265
 Type.cxx:266
 Type.cxx:267
 Type.cxx:268
 Type.cxx:269
 Type.cxx:270
 Type.cxx:271
 Type.cxx:272
 Type.cxx:273
 Type.cxx:274
 Type.cxx:275
 Type.cxx:276
 Type.cxx:277
 Type.cxx:278
 Type.cxx:279
 Type.cxx:280