root-project / root

The official repository for ROOT: analyzing, storing and visualizing big data, scientifically
https://root.cern
Other
2.66k stars 1.27k forks source link

Issue with pragma enum class in template class #16496

Open meiyasan opened 3 weeks ago

meiyasan commented 3 weeks ago

Check duplicate issues.

Description

Hello,

I have defined an enum class type, such that I can switch between mathematical representations easily.

Considering the reproducer below, I get the following error message:

Forward declarations from [..]/install/lib/libXXX.rootmap:3:11: error: unknown type name 'MyEnum'
template <MyEnum> class MyClass;
               ^

Here is an overview of the rootmap, MyEnum is not declared

{ decls }
[..]
template <MyEnum> class MyClass;
[..]
[ libXXX.dylib ]
[...]

How can I fix the root map ? It seem enum class is missing in root map so MyEnum is not defined.

Reproducer

Here are some abstractions:

# LinkDef.h
#pragma link C++ enum class MyEnum;

#pragma link C++ class MyClass<MyEnum::E0>+;
#pragma link C++ class MyClass <MyEnum::E1>+;
#pragma link C++ class MyClass <MyEnum::E2>+;

# Header.h
enum class MyEnum { E0, E1, E2 };
template <MyEnum T = MyEnum::E0>
class MyClass : public MyClassAbstract
{
    //  [...]
}

ROOT version

v6.32.04

Installation method

build from source

Operating system

macOS 15.0

Additional context

No response

vepadulano commented 3 weeks ago

Dear @xkzl ,

Thanks for your report. As a first attempt at fixing it, could you try specifying the pragma for the enum as simply

#pragma link C++ enum MyEnum;

Note the removal of the class keyword.

meiyasan commented 3 weeks ago

Ciao Vincenzo,

I have tried and the root map contains now MyEnum, but at the wrong place I believe?

{ decls }
namespace ROOT { namespace XXX {  } }
template <MyEnum> class MyClass;
[...]

[ libXXX.dylib ]
# List of selected classes
[...]
# List of selected enums and outer classes
enum MyEnum
[...]

Marco

vepadulano commented 3 weeks ago

Dear @xkzl ,

Indeed, I can see the same thing with the following simple example

// myheader.hxx
#ifndef myheader
#define myheader

enum class MyEnum
{
    kFirst,
    kSecond,
    kThird
};

template <MyEnum T>
class MyClass
{
};

#endif 
// LinkDef.h
#ifdef __CLING__
#pragma link C++ enum MyEnum;
#pragma link C++ class MyClass < MyEnum::kFirst> + ;
#pragma link C++ class MyClass < MyEnum::kSecond> + ;
#pragma link C++ class MyClass < MyEnum::kThird> + ;
#endif
$: rootcling -f myheaderdict.cxx myheader.hxx LinkDef.h -rmf myheader.rootmap
# myheader.rootmap
{ decls }
template <MyEnum> class MyClass;

[  ]
# List of selected classes
class MyClass<(MyEnum)0>
class MyClass<(MyEnum)1>
class MyClass<(MyEnum)2>
class MyClass<MyEnum::kFirst>
class MyClass<MyEnum::kSecond>
class MyClass<MyEnum::kThird>
# List of selected enums and outer classes
enum MyEnum

I am unsure whether we are missing some different configuration or spelling. @pcanal might be able to help here.

meiyasan commented 2 weeks ago

@vepadulano did you found a fix for that ? I get spam by these "Forward declarations" messages each time I open my programs. Any fix or way to remove these messages. Except seing the error message, I couldn't find any issue in the execution of my code using MyClass

meiyasan commented 2 days ago

@vepadulano @pcanal , I compiled a library on GCC 9 on Linux computer and received some additional warning information. Perhaps it might help, it seems to be harmless as my class seems to work as expected. I would be glad to find an alternative or a fix for that issue. Any input would be very welcome.

[  1%] Generating MyLibrary.Dict.cxx, libMyLibrary_rdict.pcm, libMyLibrary.rootmap
[  3%] Built target create_all_archives
Warning: Forward declarations of templates with enums as template parameters. The responsible class is: NonTypeTemplateParmDecl 0x7f306cb8b248 </path/to/my/sources/include/MyClass.h:69:11, col:29> col:17 referenced 'MyEnum' depth 0 index 0 T1
`-TemplateArgument expr
  `-ConstantExpr 0x7f306cb8b2a8 <col:22, col:29> 'MyEnum'
    |-value: Int 2
    `-DeclRefExpr 0x7f306cb8b208 <col:22, col:29> 'MyEnum' EnumConstant 0x7f306cb89020 'E0' 'MyEnum'

Warning: Problems with arguments for forward declaration of class MyClass
Warning: Forward declarations of templates with enums as template parameters. The responsible class is: NonTypeTemplateParmDecl 0x7f306cb8b248 </path/to/my/sources/include/MyClass.h:69:11, col:29> col:17 referenced 'MyEnum' depth 0 index 0 T1
`-TemplateArgument expr
  `-ConstantExpr 0x7f306cb8b2a8 <col:22, col:29> 'MyEnum'
    |-value: Int 2
    `-DeclRefExpr 0x7f306cb8b208 <col:22, col:29> 'MyEnum' EnumConstant 0x7f306cb89020 'E0' 'MyEnum'

Warning: Problems with arguments for forward declaration of class MyClass
Warning: Forward declarations of templates with enums as template parameters. The responsible class is: NonTypeTemplateParmDecl 0x7f306cb8b248 </path/to/my/sources/include/MyClass.h:69:11, col:29> col:17 referenced 'MyEnum' depth 0 index 0 T1
`-TemplateArgument expr
  `-ConstantExpr 0x7f306cb8b2a8 <col:22, col:29> 'MyEnum'
    |-value: Int 2
    `-DeclRefExpr 0x7f306cb8b208 <col:22, col:29> 'MyEnum' EnumConstant 0x7f306cb89020 'E0' 'MyEnum'