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