SourceLocation ClangAsmParserCallback::translateLocation(const llvm::SourceMgr &LSM, llvm::SMLoc SMLoc) { // Compute an offset into the inline asm buffer. // FIXME: This isn't right if .macro is involved (but hopefully, no // real-world code does that). const llvm::MemoryBuffer *LBuf = LSM.getMemoryBuffer(LSM.FindBufferContainingLoc(SMLoc)); unsigned Offset = SMLoc.getPointer() - LBuf->getBufferStart(); // Figure out which token that offset points into. const unsigned *TokOffsetPtr = std::lower_bound(AsmTokOffsets.begin(), AsmTokOffsets.end(), Offset); unsigned TokIndex = TokOffsetPtr - AsmTokOffsets.begin(); unsigned TokOffset = *TokOffsetPtr; // If we come up with an answer which seems sane, use it; otherwise, // just point at the __asm keyword. // FIXME: Assert the answer is sane once we handle .macro correctly. SourceLocation Loc = AsmLoc; if (TokIndex < AsmToks.size()) { const Token &Tok = AsmToks[TokIndex]; Loc = Tok.getLocation(); Loc = Loc.getLocWithOffset(Offset - TokOffset); } return Loc; }
/// \brief Get the source location in \arg BufferId for the given line. static SourceLocation translateLine(const llvm::SourceMgr &SM, int BufferId, unsigned Line) { const llvm::MemoryBuffer *Buffer = SM.getMemoryBuffer(BufferId); const char *Buf = Buffer->getBufferStart(); size_t BufLength = Buffer->getBufferSize(); if (BufLength == 0) return SourceLocation::getFromPointer(Buf); size_t i = 0; unsigned LineNo = 1; for (; i < BufLength && LineNo != Line; ++i) if (Buf[i] == '\n') ++LineNo; return SourceLocation::getFromPointer(Buf + i); }
bool add_source(string file) { L(cout << "### Adding file " << file << endl); std::string full_path; unsigned bufn = sm.AddIncludeFile(file, llvm::SMLoc(), full_path); if (bufn == ~0U) { cerr << "*** Could not load file " << file << ". Please check that you have spelled the interface name correctly and specified all include paths." << endl; return false; } L(cout << "### Parsing file " << file << endl); parser_t* parser = new parser_t(sm, verbose); L(cout << "### Initing parser" << endl); parser->init(sm.getMemoryBuffer(bufn)); L(cout << "### Adding parser to stack" << endl); parser_stack.push_back(parser); return true; }
/// \brief Takes a list of diagnostics that were expected to have been generated /// but were not and produces a diagnostic to the user from this. static unsigned PrintExpected(DiagnosticsEngine &Diags, llvm::SourceMgr &SourceMgr, DirectiveList &DL, const char *Kind) { if (DL.empty()) return 0; SmallString<256> Fmt; llvm::raw_svector_ostream OS(Fmt); for (DirectiveList::iterator I = DL.begin(), E = DL.end(); I != E; ++I) { Directive &D = **I; OS << "\n Line " << SourceMgr.getLineAndColumn(D.DiagnosticLoc).first; if (D.DirectiveLoc != D.DiagnosticLoc) { int BufID = SourceMgr.FindBufferContainingLoc(D.DirectiveLoc); OS << " (directive at " << SourceMgr.getMemoryBuffer(BufID)->getBufferIdentifier() << SourceMgr.getLineAndColumn(D.DirectiveLoc).first << ")"; } OS << ": " << D.Text; } Diags.Report(SourceLocation(), diag::verify_inconsistent_diags) << Kind << /*Unexpected=*/false << OS.str(); return DL.size(); }