Hi,
I am trying to compile a template class with user-defined Streamer function with ROOT linuxx8664icc and it seems that rootcint is generating the wrong code.
Here is a dummy template class that allows to reproduce the problem:
#include <cstdio>
#include "Rtypes.h"
template <typename U> class Test: public TObject
{
public:
Test(){printf("Hello World!\n");}
private:
ClassDef(Test,1)
};
template <typename U> void Test<U>::Streamer(TBuffer &R__b)
{
}
The LinkDef file is the following:
#ifdef __CINT__
#pragma link C++ class Test<Int_t>-;
#endif
I generate the dictionary file using the following command: rootcint Test_Dict.cxx -c -I./ Test.h Test_LinkDef.h
Here is the command I use to generate the object file and the error from
icc:
icc -c -o Test_Dict.o -xT -O3 -ipo -fPIC -wd1476
-I/data/data023/pldrouin/softwares/x86_64_icc/root/include -wd1572 -fPIC
Test_Dict.cxx
Test_Dict.cxx(51): error: namespace "ROOT::Shadow" has no member "Test"
R__ASSERT(sizeof(::Test<int>) == sizeof(::ROOT::Shadow::Test<int>));
^
Test_Dict.cxx(51): error: type name is not allowed
R__ASSERT(sizeof(::Test<int>) == sizeof(::ROOT::Shadow::Test<int>));
^
Test_Dict.cxx(51): error: expected an expression
R__ASSERT(sizeof(::Test<int>) == sizeof(::ROOT::Shadow::Test<int>));
^
Test_Dict.cxx(119): error: qualified name is not allowed
typedef ::ROOT::Shadow::Test<int> ShadowClass;
^
Test_Dict.cxx(119): error: expected a ";"
typedef ::ROOT::Shadow::Test<int> ShadowClass;
^
Test_Dict.cxx(120): error: identifier "ShadowClass" is undefined
ShadowClass *sobj = (ShadowClass*)obj;
^
Test_Dict.cxx(120): error: identifier "sobj" is undefined
ShadowClass *sobj = (ShadowClass*)obj;
^
Test_Dict.cxx(120): error: expected an expression
ShadowClass *sobj = (ShadowClass*)obj;
^
Test_Dict.cxx(120): error: expected a ";"
ShadowClass *sobj = (ShadowClass*)obj;
^
compilation aborted for Test_Dict.cxx (code 2) gmake: *** [Test_Dict.o] Error 2
I am using icc 10.0 20070426. Please note that this problem does not occur with linuxx86gcc, with a non-template class or with a template class with an auto-generated Streamer function. The problem seems to be related to name mangling for the class. Here is a diff of the generated dictionary files with and without user-defined Streamer functions (removing the diff due to the implementation of the Streamer function in the dictionary file in the case where it is not user-defined): 33a34,44
> #if !(defined(R__ACCESS_IN_SYMBOL) || defined(R__USE_SHADOW_CLASS))
> typedef ::Test< int > TestlEintgR;
> #else
> class TestlEintgR : public ::TObject {
> public:
> //friend XX;
> // To force the creation of a virtual table, throw just in case.
> virtual ~TestlEintgR() throw() {};
> };
> #endif
>
51c62
< R__ASSERT(sizeof(::Test<int>) == sizeof(::ROOT::Shadow::Test<int>));
---
> R__ASSERT(sizeof(::Test<int>) ==
sizeof(::ROOT::Shadow::TestlEintgR));
< &TestlEintgR_Dictionary, isa_proxy, 1, --- > &TestlEintgR_Dictionary, isa_proxy, 0, 119c147 < typedef ::ROOT::Shadow::Test<int> ShadowClass; --- > typedef ::ROOT::Shadow::TestlEintgR ShadowClass;527c555
--- > G__tagtable_setup(G__get_linked_tagnum(&G__Test_DictLN_TestlEintgR),sizeof(Test<int>),-1,28928,(char*)NULL,G__setup_memvarTestlEintgR,G__setup_memfuncTestlEintgR); Thank you! Pierre-Luc DrouinReceived on Sat Oct 04 2008 - 00:31:37 CEST
This archive was generated by hypermail 2.2.0 : Mon Oct 06 2008 - 11:50:02 CEST