Uploaded image for project: 'ROOT'
  1. ROOT
  2. ROOT-9660

cling forward declaration issue with enums



    • Bug
    • Resolution: Fixed
    • Blocker
    • 6.16/00, 6.14/10
    • 6.14/02
    • Cling
    • None
    • lxplus



      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
       mystuff::myenum one() \{ return mystuff::ONE; }

      while in the second module, we select a template type that uses the enum:

      class Y
       std::pair<mystuff::myenum, double> pp;
       <class name="Y"/>
       <class name="std::pair<mystuff::myenum, double>"/>

      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.




            dpiparo Danilo Piparo
            ssnyder Scott Snyder
            0 Vote for this issue
            7 Start watching this issue


              Actual Start:
              Actual End: