Wrong SourceRange for IfStmt ?

I want to emit some text after each if statement in source code. When testing a tool I’ve found that ifStmt->getSourceRange() sometimes returns wrong end location.

In RecursiveASTVisitor I have following code to insert “$” before and after each if:

bool VisitIfStmt(clang::IfStmt* ifStmt)
clang::tooling::Replacement rep0(compInst.getSourceManager(), ifStmt->getLocStart(), 0, “$”);
handleAllErrors ( replacements.add(rep0) );
clang::tooling::Replacement rep1(compInst.getSourceManager(), ifStmt->getLocEnd().getLocWithOffset(1), 0, “$”);
handleAllErrors ( replacements.add(rep1) );
return true;

Replacements &replacements;
ASTContext *Context;
clang::CompilerInstance &compInst;

When testing on following code:

int a;
if (a)


Result is:

$if (a)

So Clang thinks that if statement ends inside decrement operator. Is it a bug, or I misuse API?


You’re assuming that the length of the end token is 1, but you should use its actual length instead.

So, instead of getting the end location of the statement, you should get the end token, then use its location and length, e.g., tok.getLocation().getLocWithOffset(tok.getLength()).


Thanks you!
So I’ve misunderstood the meaning of API.
Here is also related discussion on stackoverflow : https://stackoverflow.com/questions/11083066/getting-the-source-behind-clangs-ast

Looks like semicolon is not considered a token, so it does not have any representation in AST.

So for example to find location after semicolon in this IfStmt:

if (a)


I have to search for semicolon myself:

const char* endCharPtr = sourceManager.getCharacterData(locEnd);
size_t offsetSemicolon = 0;

while (endCharPtr[offsetSemicolon-1]) != ‘;’ )
offsetSemicolon ++;

if there is a CompoundStmt in Then body, like

if (a)

{ a–; }

Location of final curly brace will be detected correctly.