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);
}
示例#3
0
 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;
 }
示例#4
0
/// \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();
}