[cfe-dev] Insert static data member definitions
Alfred Krohmer
devkid at devkid.net
Tue Jan 22 07:47:09 PST 2013
Hi!
I'm trying to add something reflection-like to C++ via a clang plugin.
In the test file that I want to compile I've got the following piece of
code:
#include <iostream>
template<class T> struct reflection {};
class MyTestClass {};
int main () {
std::cout << reflection<MyTestClass>::name << "\n";
return 0;
}
As you can see, I expect the "reflection" class template to provide a
static data member called "name" of the type const char*. The output
here should obviously be "MyTestClass". I have realized this so far:
ClassTemplateSpecializationDecl *rd = instantiate(
ctx,
CI.getSema(),
decl->getDeclContext(),
reflectionDef,
{TemplateArgument(decl->getTypeForDecl()->getCanonicalTypeInternal())});
QualType charType (new BuiltinType(BuiltinType::Kind::Char_S), 0);
charType.addConst();
charType = ctx.getPointerType(charType);
auto field = VarDecl::Create(
ctx,
rd,
{}, {},
&ctx.Idents.get("name"),
charType,
ctx.getTrivialTypeSourceInfo(charType, SourceLocation()),
StorageClass::SC_Static, StorageClass::SC_Static
);
CI.getSema().SetMemberAccessSpecifier(field, nullptr,
AccessSpecifier::AS_public);
field->setConstexpr(true);
field->setInitStyle(VarDecl::InitializationStyle::CInit);
Expr *expr = StringLiteral::Create(ctx, r.name,
StringLiteral::StringKind::Ascii, false, charType, SourceLocation());
field->setInit(expr);
rd->addDecl(field);
reflectionDef->getDeclContext()->addDecl(rd);
Where "decl" is the corresponding CXXRecordDecl for the MyTestClass,
"reflectionDef" is the ClassTemplateDecl of the "reflection" template
class, "r.name" contains the name of the Class ("MyTestClass") and the
"instantiate" function is taken from this post:
http://clang-developers.42468.n3.nabble.com/How-to-perform-template-substitution-in-the-clang-library-td4028413.html#a4028622
When I run clang over the test code with my plugin loaded, it compiles
just fine, but the linker seems not being able to find the definition of
the "name" data member:
/tmp/test-sLkoVj.o:../examples/test.cpp:function main: error: undefined
reference to 'reflection<A>::name'
The relevant output of the decleration context dump:
template <class T> struct reflection {
};
class A {
};
struct reflection {
static const char *name = "A";
};
Do I need to tell the Sema object that it has to instantiate the data
member correctly? (And if yes, how do I do this?)
PS: I am resending this message because I first posted it via the Nabble
interface, which seems to strip out the code I included in the message
and I didn't get an answer yet. I hope this isn't causing any trouble.
More information about the cfe-dev
mailing list