How to document macro-generated classes with Doxygen?
I use macros to generate classes in the following way:
generator.h:
class CLASS_NAME : public parent
{
//generate variables with names given by CLASS_VARIABLES using complicated
//Boost.Preprocessor stuff.
};
#undef CLASS_NAME
#undef CLASS_VARIABLES
myclass.h:
#define CLASS_NAME MyClass
#define CLASS_VARIABLES (a, b, c, x, y, z)
#include "generator.h"
The actual class is more complicated and uses various Boost.Preprocessor macros. Is there a way to automatically document the generated classes with Doxygen by adding comments to generator.h, or alternatively to generate an example class with documentation? I have tried enabling ENABLE_PREPROC开发者_StackOverflowESSING and MACRO_EXPANSION, but this does not seem to suffice.
At the time I'm writing, doxygen will perform full-blown file inclusion, provided a couple of conditions hold. From the doxygen internals documentation:
...the preprocessor parses, but not actually includes code when it encounters a #include (with the exception of #include found inside { ... } blocks)
The other undocumented, but intuitive precondition I've found through experimentation is that whatever {...} block the #include is in must itself be documented. For instance, running doxygen on the following test file utilizing Boost.Preprocessor will generate entries for structs FOO::A
, FOO::B
, and FOO::C
, provided that MACRO_EXPANSION
is enabled in the config file, the desired extraction mode is set to "All Entities", and the boost folder is properly set in INCLUDE_PATH
:
#include <boost/preprocessor/iteration/local.hpp>
#include <boost/preprocessor/tuple/elem.hpp>
#define STRUCTS (A, B, C)
namespace FOO {
#define BOOST_PP_LOCAL_MACRO(n) struct BOOST_PP_TUPLE_ELEM(3,n, STRUCTS) {};
#define BOOST_PP_LOCAL_LIMITS (0,2)
#include BOOST_PP_LOCAL_ITERATE()
}
However, removing FOO
to place the structs in an anonymous namespace will result in no documentation. So, if you can bear to #include "generator.h"
within an explicit namespace, it will work.
What about "Documentation at other places" paragraph in http://www.doxygen.nl/manual/docblocks.html
/*! \class CLASS_NAME
\brief An auto generated class
A more detailed class description.
*/
/*! \fn CLASS_NAME::CLASS_NAME()
\brief Default constuctor
*/
It won't work. The Doxygen preprocessor doesn't really perform full blown file inclusion (it only looks in the included files for macro definitions; otherwise, the ENABLE_PREPROCESSING directive would be totally useless!). So the #include "generator.h"
has no effect.
If you physically replace the #include
directive with the content of the included file, it will work. (Not very useful, I know).
Another way to do this is to modify your files like this:
generator.h:
#define DEFCLASS class CLASS_NAME : public parent \
{ \
... whatever ... \
};
myclass.h:
#define CLASS_NAME MyClass
#define CLASS_VARIABLES (a, b, c, x, y, z)
#include "generator.h"
DEFCLASS
but this will not work if you use DEFCLASS more than once per source file (probably a bug/defect of Doxygen).
I would recommend putting the generated classes in a separate header and just documenting the header. In the best case, generated classes are more of an implementation detail.
The other option would be script something up. Either using your favorite scripting language, or something like cheetah wouldn't be terrible.
I am guessing your generator looks something simple to generate boiler plate or traits or whatever.
GENERATE_CLASS(Foo);
GENERATE_CLASS(Bar);
Something like that is pretty reasonable grep fodder.
精彩评论