clang 工具:如何找到表达式的物理结尾?

问题描述

我正在使用 clang 构建一个源到源工具。我想要做的是用二元 = 运算符制作的仪器商店。目前,我在重写包含宏调用的表达式时遇到了问题。我进行了一些挖掘,发现了一些有助于我理解的信息(例如 clang fails replacing a statement if it contains a macro)。但我仍然不确定如何解决这个问题。

具体来说,假设您有:

#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(),其中 opBinaryOperator一个实例。这不起作用,因为由于宏扩展,AST 中的结束位置与表达式的物理结束位置不同。
  2. sm.getSpellingLoc(op->getEndLoc()),其中 sm 是源管理器。这只是返回 op->getEndLoc()
  3. sm.getExpansionLoc(op->getEndLoc())。这很接近,但返回的位置是宏名称的结尾,因此不会删除宏参数。

感谢您提供任何建议(或实现相同目标的更简单方法)。

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)