[ROOT] Rootcint + namespace + templated classes.

From: Brett Viren (bv@bnl.gov)
Date: Thu Jan 30 2003 - 21:10:01 MET


Hi,

I am trying to run rootcint on some 3rd party library code which is
fairly heavily templated and in its own namespace.  Rootcint is
failing to process it and I am wondering if it is a shortcoming or if
the code might actually be wrong C++.  I have been able to excerpt a
relatively small part to demonstrate the problem (files attached) and
give some (longish) details below:


I am running rootcint like:

shell> rootcint -v4 -f TestCint.cc -c  -I. -D_REENTRANT -I$ROOTSYS/include Test.h TestLinkdef.h

And the errors I get are:

Error: no such template Marshal<void> FILE:Test.h LINE:54
Error: no such template Marshal<void> FILE:Test.h LINE:54


This "Marshal" class shows up as a default template parameter in the
main class I want to use (called "Something"):

	namespace NS {
	//...
	template <class R,class Marsh=Marshal<R> >
	class Something
	{
	public:
	    Something() {}
	    ~Something() {}
	    void no_op() {}
	};
	//...
	}


I then try to use this "Something" class as a data member in my own
class which I want rootcint to process:


	class MyClass
	{
	public:
	    MyClass();
	    ~MyClass();
	    NS::Something<void> something;
	};


I find that I can make rootcint's error go away by explicitly using
the NS:: prefix in the definition of "Something" (even though it is
inside the namespace already):

	template <class R,class Marsh=NS::Marshal<R> >

However, since this code is actually from a 3rd party library, I
don't want to have to edit (unless it is just bad C++, then I'll
submit a bug report).

I can also stop the errors by adding "using namespace NS" just before
the definition of MyClass, but I still *must* use the "NS::" preface
to the "something" declaration.  Also, while going this route does let
me create a root-ified library with MyClass, when trying to access the
"something" member from inside ROOT I get an error about the NS
namespace being unkown:


root [0] gSystem->Load("libTest.so")
root [1] MyClass* mc = new MyClass
root [2] mc->something.no_op()
Error: class,struct,union or type NS not defined  FILE:/tmp/IBmZgC_cint LINE:1
*** Interpreter error recovered ***



This is on the edge of what I know about C++.  Should Rootcint be able
to handle this code, or is it incorrect C++? (G++ 3.2 compiles it
w/out warnings with -Wall and -pedantic).

I am using CVS Version 3.05/01 29 January 2003 on Debian x86, GCC 3.2.

I'll attach the Test.h and TestLinkdef.h and the generated
TestCint.{cc,h} files


Thanks,
-Brett.




namespace NS {

template <typename R>
class Marshal
{
public:
    Marshal() {}
   ~Marshal() {}
};

template <>
class Marshal<void>
{
public:
    Marshal() {}
   ~Marshal() {}
};

////Switch comments on 2 lines below to make work
//template <class R,class Marsh=NS::Marshal<R> >
template <class R,class Marsh=Marshal<R> >
class Something
{
public:
    Something() {}
    ~Something() {}
    void no_op() {}
};


template <class Marsh>
class Something<void,Marsh>
{
public:
    Something() {}
    ~Something() {}
    void no_op() {}
};


}


/// Remove comment to make work.
using namespace NS;

class MyClass
{

public:

    MyClass() {}
    ~MyClass() {}

    NS::Something<void> something;

};


#ifdef __CINT__

#pragma link off all globals;
#pragma link off all classes;
#pragma link off all functions;

#pragma link C++ class MyClass;

#endif


//
// File generated by rootcint at Thu Jan 30 15:01:37 2003.
// Do NOT change. Changes will be lost next time file is generated
//

#include "RConfig.h"
#if !defined(R__ACCESS_IN_SYMBOL)
//Break the privacy of classes -- Disabled for the moment
#define private public
#define protected public
#endif

#include "TestCint.h"
#include "TClass.h"
#include "TBuffer.h"
#include "TMemberInspector.h"
#include "TError.h"

#ifndef G__ROOT
#define G__ROOT
#endif

// Since CINT ignores the std namespace, we need to do so in this file.
namespace std {} using namespace std;

#include "RtypesImp.h"

namespace ROOT {
   namespace Shadow {
   } // Of namespace ROOT::Shadow
} // Of namespace ROOT

namespace ROOT {
   void MyClass_ShowMembers(void *obj, TMemberInspector &R__insp, char *R__parent);
   void MyClass_Dictionary();
   TClass *MyClass_IsA(const void*);
   void *new_MyClass(void *p = 0);
   void *newArray_MyClass(Long_t size);
   void delete_MyClass(void *p);
   void deleteArray_MyClass(void *p);
   void destruct_MyClass(void *p);

   // Function generating the singleton type initializer
   TGenericClassInfo *GenerateInitInstance(const MyClass*)
   {
      MyClass *ptr = 0;
      static ROOT::TGenericClassInfo 
         instance("MyClass", "Test.h", 49,
                  typeid(MyClass), DefineBehavior(ptr, ptr),
                  0, &MyClass_Dictionary, &MyClass_IsA, 0);
      instance.SetNew(&new_MyClass);
      instance.SetNewArray(&newArray_MyClass);
      instance.SetDelete(&delete_MyClass);
      instance.SetDeleteArray(&deleteArray_MyClass);
      instance.SetDestructor(&destruct_MyClass);
      return &instance;
   }
   // Static variable to force the class initialization
   static ROOT::TGenericClassInfo *_R__UNIQUE_(Init) = GenerateInitInstance((const MyClass*)0x0); R__UseDummy(_R__UNIQUE_(Init));

   // Dictionary for non-ClassDef classes
   void MyClass_Dictionary() {
      ROOT::GenerateInitInstance((const MyClass*)0x0)->GetClass();
   }

}

namespace ROOT {
   // Return the actual TClass for the object argument
   TClass *MyClass_IsA(const void *obj) {
      return gROOT->GetClass(typeid(*(::MyClass*)obj));
   }
   // Wrappers around operator new
   void *new_MyClass(void *p) {
      return  p ? ::new((ROOT::TOperatorNewHelper*)p) ::MyClass : new ::MyClass;
   }
   void *newArray_MyClass(Long_t size) {
      return new ::MyClass[size];
   }
   // Wrapper around operator delete
   void delete_MyClass(void *p) {
      delete ((::MyClass*)p);
   }
   void deleteArray_MyClass(void *p) {
      delete [] ((::MyClass*)p);
   }
   void destruct_MyClass(void *p) {
      ((::MyClass*)p)->~MyClass();
   }
} // end of namespace ROOT for class MyClass

/********************************************************
* TestCint.cc
********************************************************/

#ifdef G__MEMTEST
#undef malloc
#undef free
#endif

extern "C" void G__cpp_reset_tagtableTestCint();

extern "C" void G__set_cpp_environmentTestCint() {
  G__add_compiledheader("TROOT.h");
  G__add_compiledheader("TMemberInspector.h");
  G__add_compiledheader("Test.h");
  G__cpp_reset_tagtableTestCint();
}
class G__TestCintdOcc_tag {};

void* operator new(size_t size,G__TestCintdOcc_tag* p) {
  if(p && G__PVOID!=G__getgvp()) return((void*)p);
#ifndef G__ROOT
  return(malloc(size));
#else
  return(::operator new(size));
#endif
}

/* dummy, for exception */
#ifdef G__EH_DUMMY_DELETE
void operator delete(void *p,G__TestCintdOcc_tag* x) {
  if((long)p==G__getgvp() && G__PVOID!=G__getgvp()) return;
#ifndef G__ROOT
  free(p);
#else
  ::operator delete(p);
#endif
}
#endif

static void G__operator_delete(void *p) {
  if((long)p==G__getgvp() && G__PVOID!=G__getgvp()) return;
#ifndef G__ROOT
  free(p);
#else
  ::operator delete(p);
#endif
}

void G__DELDMY_TestCintdOcc() { G__operator_delete(0); }

extern "C" int G__cpp_dllrevTestCint() { return(30051515); }

/*********************************************************
* Member function Interface Method
*********************************************************/

/* MyClass */
static int G__MyClass_MyClass_0_0(G__value *result7,G__CONST char *funcname,struct G__param *libp,int hash) {
   MyClass *p=NULL;
   if(G__getaryconstruct()) p=new MyClass[G__getaryconstruct()];
   else p=::new((G__TestCintdOcc_tag*)G__getgvp()) MyClass;
      result7->obj.i = (long)p;
      result7->ref = (long)p;
      result7->type = 'u';
      result7->tagnum = G__get_linked_tagnum(&G__TestCintLN_MyClass);
   return(1 || funcname || hash || result7 || libp) ;
}

// automatic copy constructor
static int G__MyClass_MyClass_2_0(G__value *result7,G__CONST char *funcname,struct G__param *libp,int hash)
{
   MyClass *p;
   p=new MyClass(*(MyClass*)G__int(libp->para[0]));
   result7->obj.i = (long)p;
   result7->ref = (long)p;
   result7->type = 'u';
   result7->tagnum = G__get_linked_tagnum(&G__TestCintLN_MyClass);
   return(1 || funcname || hash || result7 || libp) ;
}

// automatic destructor
typedef MyClass G__TMyClass;
static int G__MyClass_wAMyClass_3_0(G__value *result7,G__CONST char *funcname,struct G__param *libp,int hash) {
   if(0==G__getstructoffset()) return(1);
   if(G__getaryconstruct())
     if(G__PVOID==G__getgvp())
       delete[] (MyClass *)(G__getstructoffset());
     else
       for(int i=G__getaryconstruct()-1;i>=0;i--)
         ((MyClass *)((G__getstructoffset())+sizeof(MyClass)*i))->~G__TMyClass();
   else {
     long G__Xtmp=G__getgvp();
     G__setgvp(G__PVOID);
     ((MyClass *)(G__getstructoffset()))->~G__TMyClass();
     G__setgvp(G__Xtmp);
     G__operator_delete((void*)G__getstructoffset());
   }
      G__setnull(result7);
   return(1 || funcname || hash || result7 || libp) ;
}


/* Setting up global function */

/*********************************************************
* Member function Stub
*********************************************************/

/* MyClass */

/*********************************************************
* Global function Stub
*********************************************************/

/*********************************************************
* Get size of pointer to member function
*********************************************************/
class G__Sizep2memfuncTestCint {
 public:
  G__Sizep2memfuncTestCint() {p=&G__Sizep2memfuncTestCint::sizep2memfunc;}
    size_t sizep2memfunc() { return(sizeof(p)); }
  private:
    size_t (G__Sizep2memfuncTestCint::*p)();
};

size_t G__get_sizep2memfuncTestCint()
{
  G__Sizep2memfuncTestCint a;
  G__setsizep2memfunc((int)a.sizep2memfunc());
  return((size_t)a.sizep2memfunc());
}


/*********************************************************
* virtual base class offset calculation interface
*********************************************************/

   /* Setting up class inheritance */

/*********************************************************
* Inheritance information setup/
*********************************************************/
extern "C" void G__cpp_setup_inheritanceTestCint() {

   /* Setting up class inheritance */
}

/*********************************************************
* typedef information setup/
*********************************************************/
extern "C" void G__cpp_setup_typetableTestCint() {

   /* Setting up typedef entry */
}

/*********************************************************
* Data Member information setup/
*********************************************************/

   /* Setting up class,struct,union tag member variable */

   /* MyClass */
static void G__setup_memvarMyClass(void) {
   G__tag_memvar_setup(G__get_linked_tagnum(&G__TestCintLN_MyClass));
   { MyClass *p; p=(MyClass*)0x1000; if (p) { }
   G__memvar_setup((void*)((long)(&p->something)-(long)(p)),117,0,0,G__get_linked_tagnum(&G__TestCintLN_NScLcLSomethinglEvoidcONScLcLMarshallEvoidgRsPgR),-1,-1,1,"something=",0,(char*)NULL);
   }
   G__tag_memvar_reset();
}

extern "C" void G__cpp_setup_memvarTestCint() {
}
/***********************************************************
************************************************************
************************************************************
************************************************************
************************************************************
************************************************************
************************************************************
***********************************************************/

/*********************************************************
* Member function information setup for each class
*********************************************************/
static void G__setup_memfuncMyClass(void) {
   /* MyClass */
   G__tag_memfunc_setup(G__get_linked_tagnum(&G__TestCintLN_MyClass));
   G__memfunc_setup("MyClass",700,G__MyClass_MyClass_0_0,105,G__get_linked_tagnum(&G__TestCintLN_MyClass),-1,0,0,1,1,0,"",(char*)NULL,(void*)NULL,0);
   // automatic copy constructor
   G__memfunc_setup("MyClass",700,G__MyClass_MyClass_2_0,(int)('i'),G__get_linked_tagnum(&G__TestCintLN_MyClass),-1,0,1,1,1,0,"u 'MyClass' - 11 - -",(char*)NULL,(void*)NULL,0);
   // automatic destructor
   G__memfunc_setup("~MyClass",826,G__MyClass_wAMyClass_3_0,(int)('y'),-1,-1,0,0,1,1,0,"",(char*)NULL,(void*)NULL,0);
   G__tag_memfunc_reset();
}


/*********************************************************
* Member function information setup
*********************************************************/
extern "C" void G__cpp_setup_memfuncTestCint() {
}

/*********************************************************
* Global variable information setup for each class
*********************************************************/
static void G__cpp_setup_global0() {

   /* Setting up global variables */
   G__resetplocal();


   G__resetglobalenv();
}
extern "C" void G__cpp_setup_globalTestCint() {
  G__cpp_setup_global0();
}

/*********************************************************
* Global function information setup for each class
*********************************************************/
static void G__cpp_setup_func0() {
   G__lastifuncposition();

}

static void G__cpp_setup_func1() {

   G__resetifuncposition();
}

extern "C" void G__cpp_setup_funcTestCint() {
  G__cpp_setup_func0();
  G__cpp_setup_func1();
}

/*********************************************************
* Class,struct,union,enum tag information setup
*********************************************************/
/* Setup class/struct taginfo */
G__linked_taginfo G__TestCintLN_MyClass = { "MyClass" , 99 , -1 };
G__linked_taginfo G__TestCintLN_NScLcLSomethinglEvoidcONScLcLMarshallEvoidgRsPgR = { "NS::Something<void,NS::Marshal<void> >" , 99 , -1 };

/* Reset class/struct taginfo */
extern "C" void G__cpp_reset_tagtableTestCint() {
  G__TestCintLN_MyClass.tagnum = -1 ;
  G__TestCintLN_NScLcLSomethinglEvoidcONScLcLMarshallEvoidgRsPgR.tagnum = -1 ;
}


extern "C" void G__cpp_setup_tagtableTestCint() {

   /* Setting up class,struct,union tag entry */
   G__tagtable_setup(G__get_linked_tagnum(&G__TestCintLN_MyClass),sizeof(MyClass),-1,1280,(char*)NULL,G__setup_memvarMyClass,G__setup_memfuncMyClass);
}
extern "C" void G__cpp_setupTestCint(void) {
  G__check_setup_version(30051515,"G__cpp_setupTestCint()");
  G__set_cpp_environmentTestCint();
  G__cpp_setup_tagtableTestCint();

  G__cpp_setup_inheritanceTestCint();

  G__cpp_setup_typetableTestCint();

  G__cpp_setup_memvarTestCint();

  G__cpp_setup_memfuncTestCint();
  G__cpp_setup_globalTestCint();
  G__cpp_setup_funcTestCint();

   if(0==G__getsizep2memfunc()) G__get_sizep2memfuncTestCint();
  return;
}
class G__cpp_setup_initTestCint {
  public:
    G__cpp_setup_initTestCint() { G__add_setup_func("TestCint",(G__incsetup)(&G__cpp_setupTestCint)); G__call_setup_funcs(); }
   ~G__cpp_setup_initTestCint() { G__remove_setup_func("TestCint"); }
};
G__cpp_setup_initTestCint G__cpp_setup_initializerTestCint;



/********************************************************************
* TestCint.h
********************************************************************/
#ifdef __CINT__
#error TestCint.h/C is only for compilation. Abort cint.
#endif
#include <stddef.h>
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <string.h>
#define G__ANSIHEADER
#define G__DICTIONARY
#include "G__ci.h"
extern "C" {
extern void G__cpp_setup_tagtableTestCint();
extern void G__cpp_setup_inheritanceTestCint();
extern void G__cpp_setup_typetableTestCint();
extern void G__cpp_setup_memvarTestCint();
extern void G__cpp_setup_globalTestCint();
extern void G__cpp_setup_memfuncTestCint();
extern void G__cpp_setup_funcTestCint();
extern void G__set_cpp_environmentTestCint();
}


#include "TROOT.h"
#include "TMemberInspector.h"
#include "Test.h"

#ifndef G__MEMFUNCBODY
#endif

extern G__linked_taginfo G__TestCintLN_MyClass;
extern G__linked_taginfo G__TestCintLN_NScLcLSomethinglEvoidcONScLcLMarshallEvoidgRsPgR;

/* STUB derived class for protected member access */



This archive was generated by hypermail 2b29 : Thu Jan 01 2004 - 17:50:09 MET