//===- SourceManagerInternals.h - SourceManager Internals -------*- C++ -*-===//
 
//
 
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
 
// See https://llvm.org/LICENSE.txt for license information.
 
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 
//
 
//===----------------------------------------------------------------------===//
 
//
 
/// \file
 
/// Defines implementation details of the clang::SourceManager class.
 
//
 
//===----------------------------------------------------------------------===//
 
 
 
#ifndef LLVM_CLANG_BASIC_SOURCEMANAGERINTERNALS_H
 
#define LLVM_CLANG_BASIC_SOURCEMANAGERINTERNALS_H
 
 
 
#include "clang/Basic/SourceLocation.h"
 
#include "clang/Basic/SourceManager.h"
 
#include "llvm/ADT/StringMap.h"
 
#include "llvm/ADT/StringRef.h"
 
#include "llvm/Support/Allocator.h"
 
#include <cassert>
 
#include <map>
 
#include <vector>
 
 
 
namespace clang {
 
 
 
//===----------------------------------------------------------------------===//
 
// Line Table Implementation
 
//===----------------------------------------------------------------------===//
 
 
 
struct LineEntry {
 
  /// The offset in this file that the line entry occurs at.
 
  unsigned FileOffset;
 
 
 
  /// The presumed line number of this line entry: \#line 4.
 
  unsigned LineNo;
 
 
 
  /// The ID of the filename identified by this line entry:
 
  /// \#line 4 "foo.c".  This is -1 if not specified.
 
  int FilenameID;
 
 
 
  /// Set the 0 if no flags, 1 if a system header,
 
  SrcMgr::CharacteristicKind FileKind;
 
 
 
  /// The offset of the virtual include stack location,
 
  /// which is manipulated by GNU linemarker directives.
 
  ///
 
  /// If this is 0 then there is no virtual \#includer.
 
  unsigned IncludeOffset;
 
 
 
  static LineEntry get(unsigned Offs, unsigned Line, int Filename,
 
                       SrcMgr::CharacteristicKind FileKind,
 
                       unsigned IncludeOffset) {
 
    LineEntry E;
 
    E.FileOffset = Offs;
 
    E.LineNo = Line;
 
    E.FilenameID = Filename;
 
    E.FileKind = FileKind;
 
    E.IncludeOffset = IncludeOffset;
 
    return E;
 
  }
 
};
 
 
 
// needed for FindNearestLineEntry (upper_bound of LineEntry)
 
inline bool operator<(const LineEntry &lhs, const LineEntry &rhs) {
 
  // FIXME: should check the other field?
 
  return lhs.FileOffset < rhs.FileOffset;
 
}
 
 
 
inline bool operator<(const LineEntry &E, unsigned Offset) {
 
  return E.FileOffset < Offset;
 
}
 
 
 
inline bool operator<(unsigned Offset, const LineEntry &E) {
 
  return Offset < E.FileOffset;
 
}
 
 
 
/// Used to hold and unique data used to represent \#line information.
 
class LineTableInfo {
 
  /// Map used to assign unique IDs to filenames in \#line directives.
 
  ///
 
  /// This allows us to unique the filenames that
 
  /// frequently reoccur and reference them with indices.  FilenameIDs holds
 
  /// the mapping from string -> ID, and FilenamesByID holds the mapping of ID
 
  /// to string.
 
  llvm::StringMap<unsigned, llvm::BumpPtrAllocator> FilenameIDs;
 
  std::vector<llvm::StringMapEntry<unsigned>*> FilenamesByID;
 
 
 
  /// Map from FileIDs to a list of line entries (sorted by the offset
 
  /// at which they occur in the file).
 
  std::map<FileID, std::vector<LineEntry>> LineEntries;
 
 
 
public:
 
  void clear() {
 
    FilenameIDs.clear();
 
    FilenamesByID.clear();
 
    LineEntries.clear();
 
  }
 
 
 
  unsigned getLineTableFilenameID(StringRef Str);
 
 
 
  StringRef getFilename(unsigned ID) const {
 
    assert(ID < FilenamesByID.size() && "Invalid FilenameID");
 
    return FilenamesByID[ID]->getKey();
 
  }
 
 
 
  unsigned getNumFilenames() const { return FilenamesByID.size(); }
 
 
 
  void AddLineNote(FileID FID, unsigned Offset,
 
                   unsigned LineNo, int FilenameID,
 
                   unsigned EntryExit, SrcMgr::CharacteristicKind FileKind);
 
 
 
 
 
  /// Find the line entry nearest to FID that is before it.
 
  ///
 
  /// If there is no line entry before \p Offset in \p FID, returns null.
 
  const LineEntry *FindNearestLineEntry(FileID FID, unsigned Offset);
 
 
 
  // Low-level access
 
  using iterator = std::map<FileID, std::vector<LineEntry>>::iterator;
 
 
 
  iterator begin() { return LineEntries.begin(); }
 
  iterator end() { return LineEntries.end(); }
 
 
 
  /// Add a new line entry that has already been encoded into
 
  /// the internal representation of the line table.
 
  void AddEntry(FileID FID, const std::vector<LineEntry> &Entries);
 
};
 
 
 
} // namespace clang
 
 
 
#endif // LLVM_CLANG_BASIC_SOURCEMANAGERINTERNALS_H