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