Получите SourceLocation закрывающей пары IfStmt в Clang при наличии произвольных макросов - PullRequest
0 голосов
/ 17 октября 2019

Не думаю, что это должно быть так сложно, но я нахожусь в конце.

Как вы находите место написания конечной части оператора if при наличии произвольных макросов? Я пытаюсь получить проход clang, который, когда ему присваивается номер строки, добавляет «&& 0» в конец условного выражения (поэтому все побочные эффекты все еще выполняются)

В частности, контрольные примерыЯ смотрю на:

#define SIZE 60


  if (i > SIZE) {
    return;
  }
  if (i > 10) {
    //CHECK: if (i > 10 && 0)
    return;
  }
#define DO_CAST(y,x) (y)x

#define BIG_MACRO(x)      \
  for (int j = 0; j < x; j++) {  \
    if (100 < DO_CAST(long, j + 10)) {      \
      break;                     \
    }                            \
  }

BIG_MACRO(10)

#define DO_CAST(y,x) (y)x

#define BIG_MACRO(x)            \
  for (int j = 0; j < x; j++) {        \
    if (100 < DO_CAST(long, j + 10)) { \
      break;                           \
    }                                  \
  }

#define BIGGER_OUTER_MACRO(foo) \
  printf("bigger macro");       \
  BIG_MACRO(foo);

BIGGER_OUTER_MACRO(10);

Во всех случаях я пытаюсь получить расположение источника, которое указывает на правую скобку строки if.

Я попробовал следующее, и это работает почти все. Cond - это условное условие IfStmt

SourceLocation FinalTokenStart = SM.getSpellingLoc(Cond->getLocEnd());
SourceLocation InsertPoint = Lexer::getLocForEndOfToken(FinalTokenStart, 0, SM, Opts);

// If the end of the conditional is a macro call, we will end up on the inside
// of the macro call's parens for some reason. Use this to get out of these calls
SourceLocation Next = Lexer::findLocationAfterToken(InsertPoint, tok::r_paren, SM, Opts, false);
while (Next.isValid()) {
    InsertPoint = Next.getLocWithOffset(-1);
    Next = Lexer::findLocationAfterToken(InsertPoint, tok::r_paren, SM, Opts, false);
}

TheRewriter.InsertText(InsertPoint, " && 0", true, true);

Однако в первом случае оно заканчивается

#define SIZE 60 && 0


  if (i > SIZE) {
    return;
  }

У кого-нибудь есть совет?

...