// 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); }
ast::SourceOffsetRanges getStmtSpecificOffsetRanges(clang::SourceManager& sourceManager, clang::Stmt& stmt) { auto tryStmt = clang::dyn_cast<clang::CXXTryStmt>(&stmt); if (!tryStmt) return {}; auto catchStmt = tryStmt->getHandler(0); std::array<std::array<clang::SourceLocation, 2>, 3> locRanges = { { { tryStmt->getTryLoc(), tryStmt->getTryBlock()->getLBracLoc().getLocWithOffset(1) }, { catchStmt->getCatchLoc(), catchStmt->getHandlerBlock()->getLocStart().getLocWithOffset(1) }, { catchStmt->getHandlerBlock()->getLocEnd(), catchStmt->getHandlerBlock()->getLocEnd().getLocWithOffset(1) } } }; ast::SourceOffsetRanges ranges; ranges.reserve(locRanges.size()); for (auto const& r : locRanges) ranges.emplace_back(sourceManager.getFileOffset(r[0]), sourceManager.getFileOffset(r[1])); return ranges; }
SrcRange constructSrcRange(const clang::SourceManager& sm, const clang::LangOptions& options, const clang::SourceLocation& SLoc, const clang::SourceLocation& ELoc) { unsigned start = sm.getFileOffset(SLoc); unsigned end = sm.getFileOffset(ELoc); end += clang::Lexer::MeasureTokenLength(ELoc, sm, options); return SrcRange(start, end); }
std::string MocNg::GetTag(clang::SourceLocation DeclLoc, const clang::SourceManager &SM) { clang::SourceLocation FileLoc = SM.getFileLoc(DeclLoc); clang::FileID FID = SM.getFileID(FileLoc); const llvm::MemoryBuffer *Buffer = SM.getBuffer(FID); const char *B = Buffer->getBufferStart(); int Off = SM.getFileOffset(FileLoc); int Orig = Off; while (Off > 0 && B[Off] != ';' && B[Off]!=',' && B[Off] != '}' && B[Off] != ':' /*&& B[Off] != '\n'*/ ) { Off--; } auto it_before = Tags.lower_bound(FileLoc.getLocWithOffset(Off - Orig)); auto it_after = Tags.upper_bound(FileLoc); if (it_before != Tags.end() && it_after != Tags.begin() && it_before == (--it_after)) { return it_before->second; } return {}; }