Description
hi -
While testing the ATLAS build against root 6.14.02, i ran into some issues
with how cling handles forward declarations of enums. I've managed
to put together a standalone reproducer, which is attached.
To demonstrate on lxplus:
$ ./build
|
$ python -i test.py
|
This type defines an enum in a namespace:
namespace mystuff {
|
enum myenum \{ ZERO, ONE, TWO, THREE };
|
}
|
which is used by two modules. In the first module, it's used
only in passing:
class X
|
{
|
public:
|
mystuff::myenum one() \{ return mystuff::ONE; }
|
};
|
while in the second module, we select a template type that uses the enum:
class Y
|
{
|
public:
|
std::pair<mystuff::myenum, double> pp;
|
};
|
...
|
<lcgdict>
|
<class name="Y"/>
|
<class name="std::pair<mystuff::myenum, double>"/>
|
</lcgdict>
|
If we load (in a way that triggers autoparsing) in order the first module
followed by the second, we get errors:
y_gen dictionary forward declarations' payload:5:78: error: enumeration previously declared with nonfixed underlying type
|
...mystuff{enum __attribute__((annotate("$clingAutoload$myenum.h"))) myenu...
|
^
|
./myenum.h:5:8: note: previous declaration is here
|
enum myenum \{ ZERO, ONE, TWO, THREE };
|
^
|
TInterpreter::TCling::RegisterModule:0: RuntimeWarning: Problems in compiling forward declarations for module y_gen: '
|
#line 1 "y_gen dictionary forward declarations' payload"
|
#pragma clang diagnostic ignored "-Wkeyword-compat"
|
#pragma clang diagnostic ignored "-Wignored-attributes"
|
#pragma clang diagnostic ignored "-Wreturn-type-c-linkage"
|
extern int __Cling_Autoloading_Map;
|
namespace mystuff\{enum __attribute__((annotate("$clingAutoload$myenum.h"))) myenum : unsigned int;}
|
namespace std{template <typename _T1, typename _T2> struct __attribute__((annotate("$clingAutoload$bits/stl_pair.h"))) __attribute__((annotate("$clingAutoload$string"))) pair;
|
}
|
class Y;
|
...
|
The forward declaration code here is indeed what's embededed in the C++ module
written by genreflex.
I see at least two issues related to the forward declaration of the enum here.
First, the forward declaration includes a base type, while the original
declaration does not. This is what actually causes the observed error.
However, i also noticed that TCling::RegisterModule contains code to
remove from the forward declarations any enums that have already been defined.
In principle, this should have avoided the error that we see here.
But the code in RegisterModule does not properly handle enums in namespaces.
It assumes that the forward declaration code will have the namespace
specifies on separate lines, like:
namespace mystuff{
|
enum __attribute__((annotate("$clingAutoload$myenum.h"))) myenum : unsigned int;
|
}
|
However, genreflex is actually all on a single line, which causes the code
in RegisterModule to fail completely.
One can avoid this error by adding an explicit base type to the enum,
which is what i did for the ATLAS code that first provoked this error.