1193326Sed//===--- SourceManagerInternals.h - SourceManager Internals -----*- C++ -*-===//
2193326Sed//
3193326Sed//                     The LLVM Compiler Infrastructure
4193326Sed//
5193326Sed// This file is distributed under the University of Illinois Open Source
6193326Sed// License. See LICENSE.TXT for details.
7193326Sed//
8193326Sed//===----------------------------------------------------------------------===//
9239462Sdim///
10239462Sdim/// \file
11239462Sdim/// \brief Defines implementation details of the clang::SourceManager class.
12239462Sdim///
13193326Sed//===----------------------------------------------------------------------===//
14193326Sed
15193326Sed#ifndef LLVM_CLANG_SOURCEMANAGER_INTERNALS_H
16193326Sed#define LLVM_CLANG_SOURCEMANAGER_INTERNALS_H
17193326Sed
18239462Sdim#include "clang/Basic/SourceLocation.h"
19193326Sed#include "clang/Basic/SourceManager.h"
20193326Sed#include "llvm/ADT/StringMap.h"
21193326Sed#include <map>
22193326Sed
23193326Sednamespace clang {
24193326Sed
25193326Sed//===----------------------------------------------------------------------===//
26193326Sed// Line Table Implementation
27193326Sed//===----------------------------------------------------------------------===//
28193326Sed
29193326Sedstruct LineEntry {
30239462Sdim  /// \brief The offset in this file that the line entry occurs at.
31193326Sed  unsigned FileOffset;
32198092Srdivacky
33239462Sdim  /// \brief The presumed line number of this line entry: \#line 4.
34193326Sed  unsigned LineNo;
35198092Srdivacky
36239462Sdim  /// \brief The ID of the filename identified by this line entry:
37239462Sdim  /// \#line 4 "foo.c".  This is -1 if not specified.
38193326Sed  int FilenameID;
39198092Srdivacky
40239462Sdim  /// \brief Set the 0 if no flags, 1 if a system header,
41193326Sed  SrcMgr::CharacteristicKind FileKind;
42198092Srdivacky
43239462Sdim  /// \brief The offset of the virtual include stack location,
44239462Sdim  /// which is manipulated by GNU linemarker directives.
45239462Sdim  ///
46239462Sdim  /// If this is 0 then there is no virtual \#includer.
47193326Sed  unsigned IncludeOffset;
48198092Srdivacky
49193326Sed  static LineEntry get(unsigned Offs, unsigned Line, int Filename,
50193326Sed                       SrcMgr::CharacteristicKind FileKind,
51193326Sed                       unsigned IncludeOffset) {
52193326Sed    LineEntry E;
53193326Sed    E.FileOffset = Offs;
54193326Sed    E.LineNo = Line;
55193326Sed    E.FilenameID = Filename;
56193326Sed    E.FileKind = FileKind;
57193326Sed    E.IncludeOffset = IncludeOffset;
58193326Sed    return E;
59193326Sed  }
60193326Sed};
61193326Sed
62193326Sed// needed for FindNearestLineEntry (upper_bound of LineEntry)
63193326Sedinline bool operator<(const LineEntry &lhs, const LineEntry &rhs) {
64193326Sed  // FIXME: should check the other field?
65193326Sed  return lhs.FileOffset < rhs.FileOffset;
66193326Sed}
67193326Sed
68193326Sedinline bool operator<(const LineEntry &E, unsigned Offset) {
69193326Sed  return E.FileOffset < Offset;
70193326Sed}
71193326Sed
72193326Sedinline bool operator<(unsigned Offset, const LineEntry &E) {
73193326Sed  return Offset < E.FileOffset;
74193326Sed}
75198092Srdivacky
76239462Sdim/// \brief Used to hold and unique data used to represent \#line information.
77193326Sedclass LineTableInfo {
78239462Sdim  /// \brief Map used to assign unique IDs to filenames in \#line directives.
79239462Sdim  ///
80239462Sdim  /// This allows us to unique the filenames that
81193326Sed  /// frequently reoccur and reference them with indices.  FilenameIDs holds
82193326Sed  /// the mapping from string -> ID, and FilenamesByID holds the mapping of ID
83193326Sed  /// to string.
84193326Sed  llvm::StringMap<unsigned, llvm::BumpPtrAllocator> FilenameIDs;
85193326Sed  std::vector<llvm::StringMapEntry<unsigned>*> FilenamesByID;
86198092Srdivacky
87239462Sdim  /// \brief Map from FileIDs to a list of line entries (sorted by the offset
88239462Sdim  /// at which they occur in the file).
89239462Sdim  std::map<FileID, std::vector<LineEntry> > LineEntries;
90193326Sedpublic:
91193326Sed  LineTableInfo() {
92193326Sed  }
93198092Srdivacky
94193326Sed  void clear() {
95193326Sed    FilenameIDs.clear();
96193326Sed    FilenamesByID.clear();
97193326Sed    LineEntries.clear();
98193326Sed  }
99198092Srdivacky
100193326Sed  ~LineTableInfo() {}
101198092Srdivacky
102226633Sdim  unsigned getLineTableFilenameID(StringRef Str);
103193326Sed  const char *getFilename(unsigned ID) const {
104193326Sed    assert(ID < FilenamesByID.size() && "Invalid FilenameID");
105193326Sed    return FilenamesByID[ID]->getKeyData();
106193326Sed  }
107193326Sed  unsigned getNumFilenames() const { return FilenamesByID.size(); }
108193326Sed
109239462Sdim  void AddLineNote(FileID FID, unsigned Offset,
110193326Sed                   unsigned LineNo, int FilenameID);
111239462Sdim  void AddLineNote(FileID FID, unsigned Offset,
112193326Sed                   unsigned LineNo, int FilenameID,
113193326Sed                   unsigned EntryExit, SrcMgr::CharacteristicKind FileKind);
114193326Sed
115198092Srdivacky
116239462Sdim  /// \brief Find the line entry nearest to FID that is before it.
117239462Sdim  ///
118239462Sdim  /// If there is no line entry before \p Offset in \p FID, returns null.
119239462Sdim  const LineEntry *FindNearestLineEntry(FileID FID, unsigned Offset);
120193326Sed
121193326Sed  // Low-level access
122239462Sdim  typedef std::map<FileID, std::vector<LineEntry> >::iterator iterator;
123193326Sed  iterator begin() { return LineEntries.begin(); }
124193326Sed  iterator end() { return LineEntries.end(); }
125193326Sed
126193326Sed  /// \brief Add a new line entry that has already been encoded into
127193326Sed  /// the internal representation of the line table.
128239462Sdim  void AddEntry(FileID FID, const std::vector<LineEntry> &Entries);
129193326Sed};
130193326Sed
131193326Sed} // end namespace clang
132193326Sed
133193326Sed#endif
134