clang tools: как найти физический конец выражения?

Я создаю инструмент для преобразования исходного кода с помощью clang. Что я хочу сделать, так это сохранить инструменты, сделанные с помощью двоичного оператора =. В настоящее время у меня возникают проблемы с переписыванием выражений, содержащих вызовы макросов. Я немного покопался и нашел некоторую информацию, которая помогла мне понять (например, clang не может заменить оператор, если он содержит макрос). Но я до сих пор не знаю, как решить эту проблему.

Конкретно, предположим, что у вас есть:

#define a(x) ((x) * 10 + 1)
 
class my_class {
    int x;
 
public:
    int my_function() {
        x = a(0);
        return x;
    }
};
 

Я хочу переписать это примерно так:

#ifndef _instrument_noclash
#define _instrument_noclash(name, expr, instance_no)                 \
    (*({                                                             \                                                               
        typeof(expr) *_t_instrument_no_clash##instance_no = &(expr); \
        _t_instrument_no_clash##instance_no;                         \
        }))
#endif
 
#define a(x) ((x) * 10 + 1)
 
class my_class {
        int x;
public:
        int my_function() {
                _instrument_noclash("x",(this->x=((0) * 10 + 1)),0);
                return x;
        }
};
 

Проблема (для меня) проста: как мне определить физическое расположение окончания выражения справа от знака = оператора? Без этих знаний я в конечном итоге перезаписываю конец выражения заявление. Сканируя API, кажется, что нет простого способа сделать это. Я пробовал несколько способов получить конечное исходное местоположение:

  1. op->getEndLoc(), где op — экземпляр BinaryOperator. Это не работает, потому что конечное местоположение в AST не совпадает с физическим конечным местоположением выражения из-за раскрытия макроса.
  2. sm.getSpellingLoc(op->getEndLoc()), где sm — менеджер исходного кода. Это просто возвращает op->getEndLoc().
  3. sm.getExpansionLoc(op->getEndLoc()). Это близко, но возвращаемое местоположение является концом имени макроса, поэтому аргументы макроса не удаляются.

Любые предложения (или более простой способ достижения той же цели) приветствуются.


person M. Taylor    schedule 28.04.2021    source источник
comment
Вы также можете отправить вопрос в список рассылки LLVM.   -  person prehistoricpenguin    schedule 29.04.2021