Beispiel #1
0
// Get the source range of the specified Stmt, ensuring that a semicolon is
// included, if necessary - since the clang ranges do not guarantee this.
SrcRange getStmtRangeWithSemicolon(const clang::Stmt *S,
                                   const clang::SourceManager& sm,
                                   const clang::LangOptions& options)
{
	clang::SourceLocation SLoc = sm.getExpansionLoc(S->getLocStart());
	clang::SourceLocation ELoc = sm.getExpansionLoc(S->getLocEnd());
	unsigned start = sm.getFileOffset(SLoc);
	unsigned end   = sm.getFileOffset(ELoc);

	// Below code copied from clang::Lexer::MeasureTokenLength():
	clang::SourceLocation Loc = sm.getExpansionLoc(ELoc);
	std::pair<clang::FileID, unsigned> LocInfo = sm.getDecomposedLoc(Loc);
	llvm::StringRef Buffer = sm.getBufferData(LocInfo.first);
	const char *StrData = Buffer.data()+LocInfo.second;
	clang::Lexer TheLexer(Loc, options, Buffer.begin(), StrData, Buffer.end());
	clang::Token TheTok;
	TheLexer.LexFromRawLexer(TheTok);
	// End copied code.
	end += TheTok.getLength();

	// Check if we the source range did include the semicolon.
	if (TheTok.isNot(clang::tok::semi) && TheTok.isNot(clang::tok::r_brace)) {
		TheLexer.LexFromRawLexer(TheTok);
		if (TheTok.is(clang::tok::semi)) {
			end += TheTok.getLength();
		}
	}

	return SrcRange(start, end);
}
Beispiel #2
0
SourceLocation Utils::locForNextToken(SourceLocation loc, const clang::SourceManager &sm, const clang::LangOptions &lo)
{
    std::pair<FileID, unsigned> locInfo = sm.getDecomposedLoc(loc);
    bool InvalidTemp = false;
    StringRef File = sm.getBufferData(locInfo.first, &InvalidTemp);
    if (InvalidTemp) {
        llvm::errs() << "Failed to get buffer data\n";
        return {};
    }
    const char *TokenBegin = File.data() + locInfo.second;
    Lexer lexer(sm.getLocForStartOfFile(locInfo.first), lo, File.begin(),
                TokenBegin, File.end());

    Token Tok;
    lexer.LexFromRawLexer(Tok);

    SourceLocation TokenLoc = Tok.getLocation();

    // Calculate how much whitespace needs to be skipped if any.
    unsigned NumWhitespaceChars = 0;
    const char *TokenEnd = sm.getCharacterData(TokenLoc) +
            Tok.getLength();
    unsigned char C = *TokenEnd;
    while (isHorizontalWhitespace(C)) {
        C = *(++TokenEnd);
        NumWhitespaceChars++;
    }

    // Skip \r, \n, \r\n, or \n\r
    if (C == '\n' || C == '\r') {
        char PrevC = C;
        C = *(++TokenEnd);
        NumWhitespaceChars++;
        if ((C == '\n' || C == '\r') && C != PrevC)
            NumWhitespaceChars++;
    }

    return loc.getLocWithOffset(Tok.getLength() + NumWhitespaceChars);
}