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