Clang: get list of defined macro

Hi.
Is there any way to get the list of defined Macros inside a parsed source
file using LibTooling?
I would like to use rewriter to add a define directive only if not defined
yet.

Thank you very much!

I think I found out something for my purpose. The macro should be CLVM_DEBUG.

        IdentifierInfo& info = Context.Idents.get("CLVM_DEBUG");
        if(info.hasMacroDefinition()) {
            ...
        }
        else {
             // Find SourceLocation of the first/last #define and add
CLVM_DEBUG definition
        }
        
Is it safe to do this?
I'm still wondering how to implement the else branch.

I think I found out something for my purpose. The macro should be
CLVM_DEBUG.

        IdentifierInfo& info = Context.Idents.get("CLVM_DEBUG");
        if(info.hasMacroDefinition()) {
            ...
        }

That looks correct.

        else {
             // Find SourceLocation of the first/last #define and add
CLVM_DEBUG definition
        }

Is it safe to do this?
I'm still wondering how to implement the else branch.

Well, that seems not solvable in general, but in a code base that has some
style rules, it might be solvable "well enough".

Cheers,
/Manuel

Thank you for your answer.
Unfortunately I haven-t been able to solve it yet. I'm find difficulties to
find the source location of macro definitions to remove them.
Moreover, I would like to ask you a question regarding macro expansion and
AST. In the doxygen I read that "Locations from macros, etc are not
rewritable.".
Now, suppose I define a macro like the following:

#define this_opencl_device(p, d) call_this_opencl_device(p, d);

where call_this_opencl_device is a stub function only used to mark the code
for analysis. After the analysis I would like to remove this call and
produce a "cleaned" source.
Unfortunately, the rewriter buffer doesn't contain the expanded macro (i.e.
the call) but the macro name itself. Therefore I'm not able to remove it
from the rewriter buffer (I tried).

Any suggestion to walk around this problem?

Thank you for your answer.
Unfortunately I haven-t been able to solve it yet. I'm find difficulties to
find the source location of macro definitions to remove them.
Moreover, I would like to ask you a question regarding macro expansion and
AST. In the doxygen I read that "Locations from macros, etc are not
rewritable.".
Now, suppose I define a macro like the following:

#define this_opencl_device(p, d) call_this_opencl_device(p, d);

where call_this_opencl_device is a stub function only used to mark the code
for analysis. After the analysis I would like to remove this call and
produce a "cleaned" source.
Unfortunately, the rewriter buffer doesn't contain the expanded macro (i.e.
the call) but the macro name itself. Therefore I'm not able to remove it
from the rewriter buffer (I tried).

Any suggestion to walk around this problem?

Without seeing your code, I'll not be able to help.

As far as I understand, the rewriter allows you to do textual replacements.
Thus, you'll be able to remove macro calls - you'll "just" need to figure
out where they are on the text level.

Cheers,
/Manuel

Ok, I report the essential code. The whole project is getting quite big...
The original source contains a function:

/#define this_opencl_device(p, d) call_this_opencl_device(p, d);
void call_this_opencl_device(int platform, int device) { }

kernel void map(int* a, int* b, int* c, const int size)
{
...
}

int main(int argc, const char * argv[])
{
    int a[1024];
    int b[1024];
    int c[1024];
    
    this_opencl_device(0, 1)
    map(a, b, c, 1024);
}
/

During the transformation, I collect all the function declarations with
kernel attribute and relative calls. What I would like to remove is both the
macro definition and the expanded call (this_opencl_device(0, 1)).
For each call I use a function to find a call to the function resulting from
macro expansion:

/pair<Expr*, Expr*>
OpenCLKernelCallDiscover::findDeviceAttribute(deque<CallExpr*>& attributes)
{
    pair<Expr*, Expr*> device;
    for(unsigned int i = 0; i < attributes.size(); i++) {
        if(attributes[i]->getDirectCallee()->getName().str() ==
"call_this_opencl_device") {
            Expr* platform_expr = attributes[i]->getArg(0);
            Expr* device_expr = attributes[i]->getArg(1);
            return pair<Expr*, Expr*>(platform_expr, device_expr);
        }
    }
    return pair<Expr*, Expr*>(NULL, NULL);
}/

I also store the calls (there may be other macros different from
this_opencl_device) in a deque.
I use this deque when I want to remove the calls using rewriter:

/// Remove attributes
deque<CallExpr*>& attributes = call->getAttributes();
for(unsigned int attr_index = 0; attr_index < attributes.size();
attr_index++)
    rewriter.RemoveText(attributes[attr_index]->getSourceRange()); /

Unfortunately, when I print the rewriter buffer content at the end, I still
get the macro there:

/...
// GENERATED CODE

    int a[1024];
    int b[1024];
    int c[1024];
    
    this_opencl_device(0, 1)
.../

Rewriting is something that doesn't work for me also when trying to remove
__attribute__ tagging declarations and functions declarations too.
I use custom attributes to annotate function declarations. In the
transformed code I would like them to be lifted away. I therefore do:

/AttrVec attributes = function->getAttrs();
for(Decl::attr_iterator iterator = function->attr_begin(); iterator !=
function->attr_end(); iterator++) {
   Attr* attribute = *iterator;
   rewriter.RemoveText(attribute->getRange());
}/

But this doesn't work. I tried the following walkaround:
/AttrVec attributes = function->getAttrs();
for(Decl::attr_iterator iterator = function->attr_begin(); iterator !=
function->attr_end(); iterator++) {
   Attr* attribute = *iterator;
   const char* start_location =
Context.getSourceManager().getCharacterData(attribute->getRange().getBegin());
   const char* end_location =
Context.getSourceManager().getCharacterData(attribute->getRange().getEnd());
   rewriter.RemoveText(attribute->getLocation(), (int)(end_location -
start_location));
}/

Even if it should be semantically equivalent, the walkaround works, while
the original version not.

I may argue the problem is due to the fact that function calls results from
macro expansion and Rewriter seems to work on an unexpanded source.
If I try to remove a classic CallExpr, it works fine (except it doesn't
remove the semicolon at the end).
It would be good to have the chance to do marco expansion giving code to the
rewriter.
But I might be wrong.