Hello,
I'm new to this mailing-list and to CLANG in general so please forgive
me if I ask a quite stupid question...
I've been reading a few mailing lists and webpages on CLANG now but I
can't find a clear answer to my question so I hope someone here could at
least point me to the correct resource.
My goal is simple: I want to compile a C++ code but after automatically
adding a few lines of code. Here are my question:
- can (or want) I do that with a plugin? At the beginning I wanted to
write a plugin to the front-end and change the AST but it seems (but I
hope I'm wrong) that when I use the "load" and "plugin" command line
option, I can't generate code at the end. Is it true or not?
- How should I do this transformation? The code I want to add is really
simple: I just want to add function calls in the constructor of
classes with specific class members as parameters. For example, I want
to transform:
class A {
float f;
};
class foo {
int bar;
foo() {}
};
into
class A {
float f;
};
class foo {
int bar;
foo() {baz(bar);}
};
It seems that I have two options:
* use a rewriter to add nodes within the AST, but it seems that it's
only for source to source transformation (and I would like to avoid
that if possible).
* use a TreeTransform which looks fine but I think I read somewhere
that it modifiying the AST for compiling it later wasn't always a
good idea.
From what I understood, it seems that I want to use treetransform, but I
wonder if I can use it within a plugin *and* generate code with only one
call to clang.
Any comment and pointer is more than welcome!
Thanks,
Hello,
I'm currently writing a plugin which must parse a file to add a few
lines of code. I wrote an ASTConsumer and use rewriter to insert text
and it works great but now I would like to dump the whole rewriter
buffers in a unique file.
My problems is that when my input file has included headers (which may
need to be rewritten). Ideally, I would like, for all included header
files that has been rewritten, to replace the #include by the rewritten
text but I really don't know how to do it... In fact I don't even know
how to easily access the list of included files.
I'm pretty sure that it's quite an obvious question so answer should be
somewhere but I didn't find it. Any pointer to the solution is more than
welcome!
Thanks a lot,
Hello,
I try to do source to source transformation: for that I decided (but
maybe I'm wrong) to write a plugin with an ASTConsumer and use a
rewriter to insert text. This works well when I have one file.
When there are includes in the file, it becomes a bit more tricky, at
least for me... Since I do source-to-source transformation, I create a
new file in the same directory as the original one and output the
rewriter buffers.
When I have includes, I can't create a new file in the same directory as
the original one since this file may be installed in a /usr/include or
somewhere else where the programmer has no write access. That's why I
decided that I wanted to write all the rewriten code in a unique new
file.
I though that I could just use the rewriter, and, in
HandleTranslationUnit, parse the whole file, look for includes and
replace includes with rewrite buffers when there is actually one. The
problem is that I don't know how to check that a rewrite buffers comes
from a given included file. If I have a rewrite buffer of an file
included in the file included in the main file, I don't have the name of
the intermediate include file...
Do you have any idea of how to handle this problem?
For me, source to source transformation is really not a good idea: I
would simply like to modify the ast and continue the compilation process
but I read somewhere that TreeTransform was not really a good choice for
that so I'm stuck with my source to source transformation I guess...
Any comment, pointer, or even answer to tell me that I'm not clear
enough would be more than welcomed.
Thanks a lot,
Hello,
I'm trying to write a clang plugin which must check if a particular
class derives from a class A.
When I parse the A class, I store a pointer to the CXXRecordDecl and for
other classes B, I use B->isDerivedFrom(A). This works well for template
classes like:
template <class T>
class A {
[...]
};
class B : public A<B> {
[...]
};
Here I detect that B inherits from A.
I have a problem when the B class looks like:
template <class U>
class B : public A < B<U> > {
};
Here, I go through the following code in clang:
[CXXInheritance.cpp:178]
// C++ [temp.dep]p3:
// In the definition of a class template or a member of a class template,
// if a base class of the class template depends on a template-parameter,
// the base class scope is not examined during unqualified name lookup
// either at the point of definition of the class template or member or
// during an instantiation of the class tem- plate or member.
if (BaseType->isDependentType())
continue;
So I don't detect that B inherits from A.
Do you know if there is a way to do detect that B inherits from A in
that case?
Thanks for you help,
Tricky. First, B is not a class, it's a class template. So you can easily detect whether any given instantiation derives from some instantiation of A, but in general, the question is not as easy to answer. What would isDerivedFrom() tell you about B if there was a specialization of B thus:
template <>
class B<int> { // int is easy, not worth deriving from A
};
That's the main problem with saying anything about templates: for any given set of arguments, the situation might be completely different.
That said, we have some heuristics in the error recovery for accessing members of dependent bases from a template. That is, take this code:
template <typename T>
struct A {
int i;
};
template <typename T>
struct B : A<T> {
void f() { i = 0; }
};
void g() {
B<int> b; b.f();
}
Check out the error message you get. There should be a note saying that it can find an 'i' in A, but you have to use this->i to access it. Follow the code to where it generates this diagnostic, and you can find the heuristics that look into dependent bases.
Or, alternatively, just walk the base specifiers of the primary template definition and look for instantiations of whatever template you're looking for.
Sebastian