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