How to write a C++ code generator that takes C++ c

2019-02-20 15:04发布

We have a CORBA implementation that autogenerates Java and C++ stubs for us. Because the CORBA-generated code is difficult to work with, we need to write wrappers/helpers around the CORBA code. So we have a 2-step code generation process (yes, I know this is bad):

CORBA IDL -> annoying CORBA-generated code -> useful wrappers/helper functions

Using Java's reflection, I can inspect the CORBA-generated code and use that to generate additional code. However, because C++ doesn't have reflection, I am not sure how to do this on the C++ side. Should I use a C++ parser? C++ templates?

TLDR: How to generate C++ code using generated C++ code as input?

4条回答
Melony?
2楼-- · 2019-02-20 15:44

Take a look at Clang compiler, aside from being a standalone compiler it is also intended to be used as an library in situations like the one you describe. It will provide you with parse tree on which you could do your analysis and transformations

查看更多
Fickle 薄情
3楼-- · 2019-02-20 15:45

Have you considered to take a step back and use the IDL as source for a custom code generator? Probably you have some wrapper code that hides things like duplicate, var, ptr, etc. We have a Ruby based CORBA IDL compiler that currently generates Ruby and C++ code. That could be extended with a customer generator, see http://www.remedy.nl for RIDL and R2CORBA.

Another option would be to check out the IDL to C++11 language mapping we are working on, more details on http://taox11.remedy.nl. This new language mapping is much easier to use and uses standard types and STL containers to work with.

查看更多
爱情/是我丢掉的垃圾
4楼-- · 2019-02-20 15:46

If you want to reliably process C++ source code, you need a program transformation tool that understands C++ syntax and semantics, can parse C++ code, transform the parsed representation, and regenerate valid C++ code (including the original comments). Such a tool provides in effect arbitrary metaprogramming by operating outside the language, so it is not limited by the "reflection" or "metaprogramming" facilities built into the language.

Our DMS Software Reengineering Toolkit with its C++ Front End can do this.

It has been used on a number of C++ automated transformation tasks, both (accidentally) related to CORBA-based activities. The first included reshaping interfaces for a proprietary distributed system into CORBA-compatible facets. The second reshaped a large CORBA-based application in the face of IDL changes; such changes in effect cause the code to be moved around and causes signature changes. You can find technical papers at the web site that describe the first activity; the second was done for a major defense contractor.

查看更多
forever°为你锁心
5楼-- · 2019-02-20 15:54

GCC XML could help in recovering the interface.

I'm using it to write a Prolog foreign interface for OpenGL and Horde3D rendering engine.

The interfaces I'm interested to are limited to C, but GCC XML handles C++ as well.

GCC XML parse source code interface and emits and XML AST. Then with an XML library it's fairly easy extract requested info. A nuance it's the lose of macro' symbols: AFAIK just the values survive to the parse. As an example, here (part of ) the Prolog code used to generate the FLI:

make_funcs(NameChange, Xml, FileName, Id) :-
    index_id(Xml, Indexed),

    findall(Name:Returns:ArgTypes,
        (xpath(Xml, //'Function'(@file = Id, @name = Name, @returns = ReturnsId), Function),
         typeid_indexed(Indexed, ReturnsId, Returns),
         findall(Arg:Type, (xpath(Function, //'Argument'(@name = Arg, @type = TypeId), _),
                    typeid_indexed(Indexed, TypeId, Type)), ArgTypes)
        ),
        AllFuncs),

    length(AllFuncs, LAllFuncs),
    writeln(FileName:LAllFuncs),

    fat('prolog/h3dplfi/~s.cpp', [FileName], Cpp),
    open(Cpp, write, Stream),
    maplist(\X^((X = K-A -> true ; K = X, A = []), format(Stream, K, A), nl(Stream)),
        ['#include "swi-uty.h"',
         '#include <~@>'-[call(NameChange, FileName)]
        ]),

    forall(member(F, AllFuncs), make_func(Stream, F)),
    close(Stream).

xpath (you guess it) it's the SWI-Prolog library that make analysis simpler...

查看更多
登录 后发表回答