Как поместить оператор возврата в блок, используя clang

0

Я пытаюсь разобрать файлы 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);

он помещает "}" сразу после "return".

 if(a)
 {printf("[%s:%d] OUT \n", __FUNCTION__, __LINE__);
 return }1;

Пожалуйста, помогите мне обнаружить конец местоположения отчета о возврате, чтобы закрыть "}", или, может быть, было бы труднее поставить ReturnStatement в какой-либо составной оператор или так.

Я также попытался найти конец заявления о возвращении следующим образом:

ReturnStatement->getLocStart().getLocWithOffset(strlen(retvalue) + 1);

но я могу получить возвращаемое значение в виде строки только для ImplicitCastExpr.

Благодарю.

  • 0
    ReturnStatement->getRetValue()->getLocEnd() вероятно, не помогут; так как это приведет к return 1}; ,
  • 0
    Спасибо, к сожалению, он все еще дает return }0;
Теги:
clang

2 ответа

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);
0

Это известная ошибка без простого решения.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню