如何在 Clang AST 中获取 OpaqueValueExpr 的子项
how to get the children of OpaqueValueExpr in Clang AST
我有部分AST,如下图。
这个BinaryOperator的代码是:
self.contentMode = UIViewContentModeScaleAspectFit;
然后我用ASTVisitor获取这行代码的信息
bool VisitBinaryOperator(BinaryOperator *node) {
ObjCPropertyRefExpr *lvalue = dyn_cast<ObjCPropertyRefExpr>(node->getLHS());
if (lvalue && \
lvalue->isMessagingSetter() && \
lvalue->getSetterSelector().getAsString() == "setContentMode:")
{
OpaqueValueExpr *rvalue = dyn_cast<OpaqueValueExpr>(node->getRHS());
// I want to get DeclRefExpr of UIViewContentModeScaleAspectFit here.
}
return true;
}
我可以得到lvalue
,但是我怎样才能得到AST最后一行的DeclRefExpr
。
OpaqueValueExpr
包含另一个表达式,您可以使用方法 getSourceExpr()
.
访问它
在你的 AST 中,源表达式将是一个隐式转换,这不是目标。为此,Clang 的 Expr
class 具有 'ignore' 方法系列,例如 IgnoreImpCasts
或 IgnoreParens
。这些方法用于访问底层表达式,就像您的情况一样。
例如,如果表达式 a
具有类型 ImplicitCastExpr
并且它包含一些类型 DeclRefExpr
的 b
,那么 a->IgnoreImpCasts()
将 return 指向 b
的指针。但是,如果我们在 b
上调用该方法,那么它将 return b
本身。
这是回答您问题的代码:
Expr *SE = rvalue->getSourceExpr()->IgnoreImpCasts();
if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(SE)) {
// do you magic with DeclRefExpr here
}
我有部分AST,如下图。
这个BinaryOperator的代码是:
self.contentMode = UIViewContentModeScaleAspectFit;
然后我用ASTVisitor获取这行代码的信息
bool VisitBinaryOperator(BinaryOperator *node) {
ObjCPropertyRefExpr *lvalue = dyn_cast<ObjCPropertyRefExpr>(node->getLHS());
if (lvalue && \
lvalue->isMessagingSetter() && \
lvalue->getSetterSelector().getAsString() == "setContentMode:")
{
OpaqueValueExpr *rvalue = dyn_cast<OpaqueValueExpr>(node->getRHS());
// I want to get DeclRefExpr of UIViewContentModeScaleAspectFit here.
}
return true;
}
我可以得到lvalue
,但是我怎样才能得到AST最后一行的DeclRefExpr
。
OpaqueValueExpr
包含另一个表达式,您可以使用方法 getSourceExpr()
.
在你的 AST 中,源表达式将是一个隐式转换,这不是目标。为此,Clang 的 Expr
class 具有 'ignore' 方法系列,例如 IgnoreImpCasts
或 IgnoreParens
。这些方法用于访问底层表达式,就像您的情况一样。
例如,如果表达式 a
具有类型 ImplicitCastExpr
并且它包含一些类型 DeclRefExpr
的 b
,那么 a->IgnoreImpCasts()
将 return 指向 b
的指针。但是,如果我们在 b
上调用该方法,那么它将 return b
本身。
这是回答您问题的代码:
Expr *SE = rvalue->getSourceExpr()->IgnoreImpCasts();
if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(SE)) {
// do you magic with DeclRefExpr here
}