I have a C++ project that uses a C bison parser. The C parser uses a struct of function pointers to call functions that create proper AST nodes when productions are reduced by bison:
typedef void Node;
struct Actions {
Node *(*newIntLit)(int val);
Node *(*newAsgnExpr)(Node *left, Node *right);
/* ... */
};
Now, in the C++ part of the project, i fill those pointers
class AstNode {
/* ... */
};
class IntLit : public AstNode {
/* ... */
};
extern "C" {
Node *newIntLit(int val) {
return (Node*)new IntLit(val);
}
/* ... */
}
Actions createActions() {
Actions a;
a.newIntLit = &newIntLit;
/* ... */
return a;
}
Now the only reason i put them within extern "C"
is because i want them to have C calling conventions. But optimally, i would like their names still be mangled. They are never called by-name from C code, so name mangling isn't an issue. Having them mangled will avoid name conflicts, since some actions are called like error
, and the C++ callback function has ugly names like the following just to avoid name clashes with other modules.
extern "C" {
void uglyNameError(char const *str) {
/* ... */
}
/* ... */
}
a.error = &uglyNameError;
I wondered whether it could be possible by merely giving the function type C linkage
extern "C" void fty(char const *str);
namespace {
fty error; /* Declared! But i can i define it with that type!? */
}
Any ideas? I'm looking for Standard-C++ solutions.