ROOT logo
// @(#)root/reflex:$Id: ClassBuilder.cxx 26631 2008-12-03 15:50:16Z axel $
// Author: Stefan Roiser 2004

// Copyright CERN, CH-1211 Geneva 23, 2004-2006, All rights reserved.
//
// Permission to use, copy, modify, and distribute this software for any
// purpose is hereby granted without fee, provided that this copyright and
// permissions notice appear in all copies and derivatives.
//
// This software is provided "as is" without express or implied warranty.

#ifndef REFLEX_BUILD
#define REFLEX_BUILD
#endif

#include "Reflex/Builder/ClassBuilder.h"

#include "Reflex/Type.h"
#include "Reflex/Member.h"

#include "Class.h"
#include "ClassTemplateInstance.h"
#include "Reflex/Tools.h"
#include "Typedef.h"
#include "Enum.h"
#include "DataMember.h"
#include "FunctionMemberTemplateInstance.h"


//______________________________________________________________________________
//______________________________________________________________________________
//
//
//  ClassBuilderImpl
//
//

//______________________________________________________________________________
Reflex::ClassBuilderImpl::ClassBuilderImpl(const char* nam, const std::type_info& ti, size_t size, unsigned int modifiers, TYPE typ)
: fClass(0)
, fLastMember()
{
   // -- Construct a class information (internal).
   std::string nam2(nam);
   const Type& c = Type::ByName(nam2);
   if (c) {
      // We found a typedef to a class with the same name
      if (c.IsTypedef()) {
         nam2 += " @HIDDEN@";
      }
      // Class already exists. Check if it was a class.
      else if (!c.IsClass()) {
         throw RuntimeError("Attempt to replace a non-class type with a class"); // FIXME: We should not throw!
      }
   }
   if (Tools::IsTemplated(nam)) {
      fClass = new ClassTemplateInstance(nam2.c_str(), size, ti, modifiers);
   }
   else {
      fClass = new Class(nam2.c_str(), size, ti, modifiers, typ);
   }
}

//______________________________________________________________________________
Reflex::ClassBuilderImpl::~ClassBuilderImpl()
{
   // -- ClassBuilderImpl destructor. Used for call back functions (e.g. Cintex).
   FireClassCallback(fClass->ThisType());
}

//______________________________________________________________________________
void Reflex::ClassBuilderImpl::AddBase(const Type& bas, OffsetFunction offsFP, unsigned int modifiers)
{
   // -- Add base class information (internal).
   fClass->AddBase(bas, offsFP, modifiers);
}

//______________________________________________________________________________
void Reflex::ClassBuilderImpl::AddDataMember(const char* nam, const Type& typ, size_t offs, unsigned int modifiers)
{
   // -- Add data member info (internal).
   fLastMember = Member(new DataMember(nam, typ, offs, modifiers));
   fClass->AddDataMember(fLastMember);
}

//______________________________________________________________________________
void Reflex::ClassBuilderImpl::AddFunctionMember(const char* nam, const Type& typ, StubFunction stubFP, void* stubCtx, const char* params, unsigned int modifiers)
{
   // -- Add function member info (internal).
   if (Tools::IsTemplated(nam)) {
      fLastMember = Member(new FunctionMemberTemplateInstance(nam, typ, stubFP, stubCtx, params, modifiers, *(dynamic_cast<ScopeBase*>(fClass))));
   }
   else {
      fLastMember = Member(new FunctionMember(nam, typ, stubFP, stubCtx, params, modifiers));
   }
   fClass->AddFunctionMember(fLastMember);
}

//______________________________________________________________________________
void Reflex::ClassBuilderImpl::AddTypedef(const Type& typ, const char* def)
{
   // -- Add typedef info (internal).
   Type ret = Type::ByName(def);
   // Check for typedef AA AA;
   if (ret == typ && ! typ.IsTypedef()) {
      if (typ) {
         typ.ToTypeBase()->HideName();
      }
      else {
         ((TypeName*)typ.Id())->HideName();
      }
   }
   // We found the typedef type
   else if (ret) {
      fClass->AddSubType(ret);
   }
   // Create a new typedef
   else {
      new Typedef(def , typ);
   }
}

//______________________________________________________________________________
void Reflex::ClassBuilderImpl::AddEnum(const char* nam, const char* values, const std::type_info* ti, unsigned int modifiers)
{
   // -- Add enum info (internal).

   // This does not work because the EnumTypeBuilder does a definition of the enum
   // not only a declaration. (It is called in the dictionary header already)
   //   EnumTypeBuilder(nam, values, *ti, modifiers);

   Enum* e = new Enum(nam, *ti, modifiers);

   std::vector<std::string> valVec = std::vector<std::string>();
   Tools::StringSplit(valVec, values, ";");

   for (
      std::vector<std::string>::const_iterator it = valVec.begin();
      it != valVec.end();
      ++it
   ) {
      std::string name;
      std::string value;
      Tools::StringSplitPair(name, value, *it, "=");
      unsigned long int valInt = atol(value.c_str());
      e->AddDataMember(Member(new DataMember(name.c_str(), Type::ByName("int"), valInt, 0)));
   }
}

//______________________________________________________________________________
void Reflex::ClassBuilderImpl::AddProperty(const char* key, const char* value)
{
   // -- Add property info (internal).
   AddProperty(key, Any(value));
}

//______________________________________________________________________________
void Reflex::ClassBuilderImpl::AddProperty(const char* key, Any value)
{
   // -- Add property info (internal).
   if (fLastMember) {
      fLastMember.Properties().AddProperty(key, value);
   }
   else {
      fClass->Properties().AddProperty(key, value);
   }
}

//______________________________________________________________________________
void Reflex::ClassBuilderImpl::SetSizeOf(size_t size)
{
   // -- Set the size of the class (internal).
   fClass->SetSize(size);
}

//______________________________________________________________________________
Reflex::Type Reflex::ClassBuilderImpl::ToType()
{
   // -- Return the type currently being built.
   return fClass->ThisType();
}

//______________________________________________________________________________
//______________________________________________________________________________
//
//
//  ClassBuilder
//
//

//______________________________________________________________________________
Reflex::ClassBuilder::ClassBuilder(const char* nam, const std::type_info& ti, size_t size, unsigned int modifiers, TYPE typ)
: fClassBuilderImpl(nam, ti, size, modifiers, typ)
{
   // -- Constructor
}

//______________________________________________________________________________
Reflex::ClassBuilder::~ClassBuilder()
{
   // -- Destructor
}

//______________________________________________________________________________
Reflex::ClassBuilder& Reflex::ClassBuilder::AddBase(const Type& bas, OffsetFunction offsFP, unsigned int modifiers)
{
   // -- Add base class information to this class.
   fClassBuilderImpl.AddBase(bas, offsFP, modifiers);
   return *this;
}

//______________________________________________________________________________
Reflex::ClassBuilder& Reflex::ClassBuilder::AddDataMember(const Type&  typ, const char*  nam, size_t offs, unsigned int modifiers)
{
   // -- Add data member info to this class.
   fClassBuilderImpl.AddDataMember(nam, typ, offs, modifiers);
   return *this;
}

//______________________________________________________________________________
Reflex::ClassBuilder& Reflex::ClassBuilder::AddFunctionMember(const Type& typ, const char* nam, StubFunction stubFP, void* stubCtx, const char* params, unsigned int modifiers)
{
   // -- Add function member info to this class.
   fClassBuilderImpl.AddFunctionMember(nam, typ, stubFP, stubCtx, params, modifiers);
   return *this;
}


//______________________________________________________________________________
Reflex::ClassBuilder& Reflex::ClassBuilder::AddTypedef(const char* typ, const char* def)
{
   // -- Add typedef info to this class.
   fClassBuilderImpl.AddTypedef(TypeBuilder(typ), def);
   return *this;
}

//______________________________________________________________________________
Reflex::ClassBuilder& Reflex::ClassBuilder::AddTypedef(const Type& typ, const char* def)
{
   // -- Add typedef info to this class.
   fClassBuilderImpl.AddTypedef(typ, def);
   return *this;
}


//______________________________________________________________________________
Reflex::ClassBuilder& Reflex::ClassBuilder::AddEnum(const char* nam, const char* values, const std::type_info* ti, unsigned int modifiers)
{
   // -- Add enum info to this class.
   fClassBuilderImpl.AddEnum(nam, values, ti, modifiers);
   return *this;
}

/*
//______________________________________________________________________________
Reflex::ClassBuilder& Reflex::ClassBuilder::addUnion(const char* nam, const char* values, unsigned int modifiers)
{
  fClassBuilderImpl.addUnion(nam, values, modifiers);
  return *this;
}
*/

//______________________________________________________________________________
Reflex::ClassBuilder& Reflex::ClassBuilder::SetSizeOf(size_t size)
{
// Set the class's size.
   fClassBuilderImpl.SetSizeOf(size);
   return *this;
}

//______________________________________________________________________________
Reflex::Type Reflex::ClassBuilder::ToType()
{
   // -- Return the type currently being built.
   return fClassBuilderImpl.ToType();
}

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