我正在尝试解析C文件并使用clang在函数的出口点添加调试。
我可以在返回之前添加调试,或者使用以下代码退出函数
if (isa<ReturnStmt>(s)) {
ReturnStmt *ReturnStatement = cast<ReturnStmt>(s);
TheRewriter.InsertText(ReturnStatement->getLocStart(), "{printf(\"[%s:%d] OUT \\n\", __FUNCTION__, __LINE__);\n", true, true);
}
但它不适合这样的功能:
//before preprocessing
int foo(int a)
{
if(a)
return 1;
else
return a;
}
//after
int foo(int a)
{
if(a)
{printf("[%s:%d] OUT \n", __FUNCTION__, __LINE__);
return 1;
else
{printf("[%s:%d] OUT \n", __FUNCTION__, __LINE__);
return a;
}
不幸的是,简单的getLocEnd不起作用。
TheRewriter.InsertText(ReturnStatement->getLocEnd(), "}", true, true);
它在“返回”之后放置“}”。
if(a)
{printf("[%s:%d] OUT \n", __FUNCTION__, __LINE__);
return }1;
请帮助我检测Return Statement位置的结束,关闭“}”或者将ReturnStatement放入某个复合语句中可能不那么困难。
我也试过像这样找到Return Statement的结尾:
ReturnStatement->getLocStart().getLocWithOffset(strlen(retvalue) + 1);
但我只能在ImplicitCastExpr的字符串视图中获得返回值。
感谢。
答案 0 :(得分:0)
它是known bug而没有简单的解决方案。
答案 1 :(得分:0)
这里我们有一个答案。我在这里找到了: https://github.com/loarabia/Clang-tutorial/blob/master/CIrewriter.cpp
你需要的只是:
// Note Stmt::getLocEnd() returns the source location prior to the
// token at the end of the line. For instance, for:
// var = 123;
// ^---- getLocEnd() points here.
SourceLocation END = stmt->getLocEnd();
// MeasureTokenLength gets us past the last token, and adding 1 gets
// us past the ';'.
int offset = Lexer::MeasureTokenLength(END,
TheRewriter.getSourceMgr(),
TheRewriter.getLangOpts()) + 1;
SourceLocation END1 = END.getLocWithOffset(offset);
TheRewriter.InsertText(END1, "\n}", true, true);