PPCallbacks - Get Hash Location

Hello all,

I’m writing a clang-tidy check for LLVM 14.0.5 that involves the preprocessor. When ifndef, define, and endif are encountered, I want to record the location of the hash token as well as the macro, so that I can issue a replacement for the entire directive. As far as I can tell, the PPCallbacks functions don’t take a parameter for the hash token location. I’m trying to get it by turning on backtracking in the lexer, but not having much luck. Could someone help me out? Ideally, PPCallbacks should provide the location of the hash token. However, I’m stuck with LLVM 14.0.5 for now, so I’m trying to backtrack as a workaround.

I got it working. I based this off of Lexer::getRawToken():

SourceLocation GetLastHash(Preprocessor* PP, SourceLocation Loc)
{
  SourceManager& SM = PP->getSourceManager();
  Loc = SM.getExpansionLoc(Loc);
  FileID FID = SM.getFileID(Loc);
  const FileEntry* Entry = SM.getFileEntryForID(FID);
  if (!Entry) {
    return SourceLocation{};
  }

  Lexer MyLexer(FID, SM.getMemoryBufferForFileOrFake(Entry), SM,
                PP->getLangOpts());
  Token Tok;
  SourceLocation LastLoc;

  do {
    MyLexer.LexFromRawLexer(Tok);
    if (Tok.getKind() == tok::TokenKind::hash) {
      LastLoc = Tok.getLocation();
    }
  } while (SM.getFileOffset(Tok.getLocation()) < SM.getFileOffset(Loc));

  return LastLoc;
}