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_SOURCEMANAGER_INTERNALS_H 16 #define LLVM_CLANG_SOURCEMANAGER_INTERNALS_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: LineTableInfo()91 LineTableInfo() { 92 } 93 clear()94 void clear() { 95 FilenameIDs.clear(); 96 FilenamesByID.clear(); 97 LineEntries.clear(); 98 } 99 ~LineTableInfo()100 ~LineTableInfo() {} 101 102 unsigned getLineTableFilenameID(StringRef Str); getFilename(unsigned ID)103 const char *getFilename(unsigned ID) const { 104 assert(ID < FilenamesByID.size() && "Invalid FilenameID"); 105 return FilenamesByID[ID]->getKeyData(); 106 } getNumFilenames()107 unsigned getNumFilenames() const { return FilenamesByID.size(); } 108 109 void AddLineNote(FileID FID, unsigned Offset, 110 unsigned LineNo, int FilenameID); 111 void AddLineNote(FileID FID, unsigned Offset, 112 unsigned LineNo, int FilenameID, 113 unsigned EntryExit, SrcMgr::CharacteristicKind FileKind); 114 115 116 /// \brief Find the line entry nearest to FID that is before it. 117 /// 118 /// If there is no line entry before \p Offset in \p FID, returns null. 119 const LineEntry *FindNearestLineEntry(FileID FID, unsigned Offset); 120 121 // Low-level access 122 typedef std::map<FileID, std::vector<LineEntry> >::iterator iterator; begin()123 iterator begin() { return LineEntries.begin(); } end()124 iterator end() { return LineEntries.end(); } 125 126 /// \brief Add a new line entry that has already been encoded into 127 /// the internal representation of the line table. 128 void AddEntry(FileID FID, const std::vector<LineEntry> &Entries); 129 }; 130 131 } // end namespace clang 132 133 #endif 134