1 //===--- SourceManagerInternals.h - SourceManager Internals -----*- C++ -*-===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 ///
10 /// \file
11 /// \brief Defines implementation details of the clang::SourceManager class.
12 ///
13 //===----------------------------------------------------------------------===//
14 
15 #ifndef LLVM_CLANG_BASIC_SOURCEMANAGERINTERNALS_H
16 #define LLVM_CLANG_BASIC_SOURCEMANAGERINTERNALS_H
17 
18 #include "clang/Basic/SourceLocation.h"
19 #include "clang/Basic/SourceManager.h"
20 #include "llvm/ADT/StringMap.h"
21 #include <map>
22 
23 namespace clang {
24 
25 //===----------------------------------------------------------------------===//
26 // Line Table Implementation
27 //===----------------------------------------------------------------------===//
28 
29 struct LineEntry {
30   /// \brief The offset in this file that the line entry occurs at.
31   unsigned FileOffset;
32 
33   /// \brief The presumed line number of this line entry: \#line 4.
34   unsigned LineNo;
35 
36   /// \brief The ID of the filename identified by this line entry:
37   /// \#line 4 "foo.c".  This is -1 if not specified.
38   int FilenameID;
39 
40   /// \brief Set the 0 if no flags, 1 if a system header,
41   SrcMgr::CharacteristicKind FileKind;
42 
43   /// \brief The offset of the virtual include stack location,
44   /// which is manipulated by GNU linemarker directives.
45   ///
46   /// If this is 0 then there is no virtual \#includer.
47   unsigned IncludeOffset;
48 
getLineEntry49   static LineEntry get(unsigned Offs, unsigned Line, int Filename,
50                        SrcMgr::CharacteristicKind FileKind,
51                        unsigned IncludeOffset) {
52     LineEntry E;
53     E.FileOffset = Offs;
54     E.LineNo = Line;
55     E.FilenameID = Filename;
56     E.FileKind = FileKind;
57     E.IncludeOffset = IncludeOffset;
58     return E;
59   }
60 };
61 
62 // needed for FindNearestLineEntry (upper_bound of LineEntry)
63 inline bool operator<(const LineEntry &lhs, const LineEntry &rhs) {
64   // FIXME: should check the other field?
65   return lhs.FileOffset < rhs.FileOffset;
66 }
67 
68 inline bool operator<(const LineEntry &E, unsigned Offset) {
69   return E.FileOffset < Offset;
70 }
71 
72 inline bool operator<(unsigned Offset, const LineEntry &E) {
73   return Offset < E.FileOffset;
74 }
75 
76 /// \brief Used to hold and unique data used to represent \#line information.
77 class LineTableInfo {
78   /// \brief Map used to assign unique IDs to filenames in \#line directives.
79   ///
80   /// This allows us to unique the filenames that
81   /// frequently reoccur and reference them with indices.  FilenameIDs holds
82   /// the mapping from string -> ID, and FilenamesByID holds the mapping of ID
83   /// to string.
84   llvm::StringMap<unsigned, llvm::BumpPtrAllocator> FilenameIDs;
85   std::vector<llvm::StringMapEntry<unsigned>*> FilenamesByID;
86 
87   /// \brief Map from FileIDs to a list of line entries (sorted by the offset
88   /// at which they occur in the file).
89   std::map<FileID, std::vector<LineEntry> > LineEntries;
90 public:
clear()91   void clear() {
92     FilenameIDs.clear();
93     FilenamesByID.clear();
94     LineEntries.clear();
95   }
96 
97   unsigned getLineTableFilenameID(StringRef Str);
getFilename(unsigned ID)98   const char *getFilename(unsigned ID) const {
99     assert(ID < FilenamesByID.size() && "Invalid FilenameID");
100     return FilenamesByID[ID]->getKeyData();
101   }
getNumFilenames()102   unsigned getNumFilenames() const { return FilenamesByID.size(); }
103 
104   void AddLineNote(FileID FID, unsigned Offset,
105                    unsigned LineNo, int FilenameID);
106   void AddLineNote(FileID FID, unsigned Offset,
107                    unsigned LineNo, int FilenameID,
108                    unsigned EntryExit, SrcMgr::CharacteristicKind FileKind);
109 
110 
111   /// \brief Find the line entry nearest to FID that is before it.
112   ///
113   /// If there is no line entry before \p Offset in \p FID, returns null.
114   const LineEntry *FindNearestLineEntry(FileID FID, unsigned Offset);
115 
116   // Low-level access
117   typedef std::map<FileID, std::vector<LineEntry> >::iterator iterator;
begin()118   iterator begin() { return LineEntries.begin(); }
end()119   iterator end() { return LineEntries.end(); }
120 
121   /// \brief Add a new line entry that has already been encoded into
122   /// the internal representation of the line table.
123   void AddEntry(FileID FID, const std::vector<LineEntry> &Entries);
124 };
125 
126 } // end namespace clang
127 
128 #endif
129