Re: linuxx8664icc: Problem with rootcint when generating dictionary files for a template class which Streamer function is user-defined

From: Fons Rademakers <Fons.Rademakers_at_cern.ch>
Date: Mon, 6 Oct 2008 11:39:27 +0200


Hi,

   using the ROOT trunk with icc 10.1 on Linux x86-64 works fine with the example you gave:

(pcsalo) [145] rootcint Test_Dict.cxx -c -I./ Test.h Test_LinkDef.h (pcsalo) [146] icc -c -o Test_Dict.o -xT -O3 -ipo -fPIC -wd1476 -Iroot/include -wd1572 Test_Dict.cxx
(pcsalo) [147] icc -V
Intel(R) C Compiler for applications running on Intel(R) 64, Version 10.1

   Build 20080312 Package ID: l_cc_p_10.1.015 Copyright (C) 1985-2008 Intel Corporation. All rights reserved. FOR NON-COMMERCIAL USE ONLY Cheers, Fons.

Axel Naumann wrote:

> Hi,
> 
> the name mangling is done by CINT, independently of the compiler used to build
> the dictionary. So my first assumption would be that you are using a version of
> ROOT that failed to mangle the template, and that we have fixed it in a later
> version.
> 
> If that isn't it we have to find out whether ICC miscompiled CINT. Looking at
> the diff
> 
> <                   &TestlEintgR_Dictionary, isa_proxy, 1,
> ---

>> &TestlEintgR_Dictionary, isa_proxy, 0,
> > and > < G__tagtable_setup(...,94464,... > ---

>> G__tagtable_setup(...,28928,...
> 
> it seems like CINT does not remember that the Linkdef statement ends with a
> "-". On the other hand you are saying that the Streamer() function does get
> suppressed in the generated dictionary file, so CINT must have noticed it. I
> also checked with valgrind but it didn't report anything.
> 
> I don't have ICC 10.0 20070426; I'll try to hunt it down once you have
> confirmed that you use the same ROOT version for ICC and GCC.
> 
> Cheers, Axel.
> 
> On 2008-10-04 0:31, Pierre-Luc Drouin wrote:

>> 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));
>> 57c68
>> < &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,94464,(char*)NULL,G__setup_memvarTestlEintgR,G__setup_memfuncTestlEintgR);
>>

>> ---
>>>   

>> 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 Drouin
>>
>>
> 

-- 
Org:    CERN, European Laboratory for Particle Physics.
Mail:   1211 Geneve 23, Switzerland
E-Mail: Fons.Rademakers_at_cern.ch              Phone: +41 22 7679248
WWW:    http://fons.rademakers.org           Fax:   +41 22 7669640
Received on Mon Oct 06 2008 - 11:39:31 CEST

This archive was generated by hypermail 2.2.0 : Mon Oct 06 2008 - 17:50:02 CEST