[cfe-dev] Clang: get list of defined macro

GabrieleCocco cocco at di.unipi.it
Tue Oct 30 09:27:04 PDT 2012


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.





--
View this message in context: http://clang-developers.42468.n3.nabble.com/Clang-get-list-of-defined-macro-tp4027815p4027844.html
Sent from the Clang Developers mailing list archive at Nabble.com.



More information about the cfe-dev mailing list