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