Issue with pragma enum class in template class
Check duplicate issues.
- [x] Checked for duplicates
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
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.
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
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.
@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
@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'
@vepadulano @dpiparo would it be possible to advice on some fixes in a reasonable timescale ? I would be happy to contribute, but I basically have not entrypoint to start with. It makes root very unfriendly to use.
At the moment the rootmap file does not support enum (nor C++20 concepts). For enums, the situations can be improved for enum class which can be forward declared (but old style enums can not be).
There is 2 solution to this problem, either move to using 'c++ module' for the dictionary containing those enums (and class template whose arguments are enum types) but this feature is still somewhat experimental. ( you will need to write a 'modulemap' file and use the options shown by rootcling --help | grep module).
The second option is to update the forward declaration writer used for the rootmap files to support enum class. (The main part is at https://github.com/root-project/root/blob/master/interpreter/cling/lib/Interpreter/ForwardDeclPrinter.cpp)
@pcanal Thank for your reply. This issue was resolved few weeks ago, thanks to your help on the ROOT forum. https://root-forum.cern.ch/t/issue-with-pragma-enum-class-in-template-class/62547/6
I am now relying on the cxxmodules you mentioned using -Druntime_cxxmodules=ON in my cmake.
I could make module.map name dynamic using CLING_MODULEMAP_FILES customization.
Thank you.
PS: For the records, please find attached the files used to demonstrate the issue and use cxxmodules as replacement. cxxmodules.zip
I just close, but of course, we can reopen if you plan to support rootmap enhancement.
Hi @meiyasan, @vepadulano,
It appears this issue is closed, but wasn't yet added to a project. Please add upcoming versions that will include the fix, or 'not applicable' otherwise.
Sincerely, :robot: