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 /// 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 "llvm/ADT/StringRef.h" 22 #include "llvm/Support/Allocator.h" 23 #include <cassert> 24 #include <map> 25 #include <vector> 26 27 namespace clang { 28 29 //===----------------------------------------------------------------------===// 30 // Line Table Implementation 31 //===----------------------------------------------------------------------===// 32 33 struct LineEntry { 34 /// The offset in this file that the line entry occurs at. 35 unsigned FileOffset; 36 37 /// The presumed line number of this line entry: \#line 4. 38 unsigned LineNo; 39 40 /// The ID of the filename identified by this line entry: 41 /// \#line 4 "foo.c". This is -1 if not specified. 42 int FilenameID; 43 44 /// Set the 0 if no flags, 1 if a system header, 45 SrcMgr::CharacteristicKind FileKind; 46 47 /// The offset of the virtual include stack location, 48 /// which is manipulated by GNU linemarker directives. 49 /// 50 /// If this is 0 then there is no virtual \#includer. 51 unsigned IncludeOffset; 52 getLineEntry53 static LineEntry get(unsigned Offs, unsigned Line, int Filename, 54 SrcMgr::CharacteristicKind FileKind, 55 unsigned IncludeOffset) { 56 LineEntry E; 57 E.FileOffset = Offs; 58 E.LineNo = Line; 59 E.FilenameID = Filename; 60 E.FileKind = FileKind; 61 E.IncludeOffset = IncludeOffset; 62 return E; 63 } 64 }; 65 66 // needed for FindNearestLineEntry (upper_bound of LineEntry) 67 inline bool operator<(const LineEntry &lhs, const LineEntry &rhs) { 68 // FIXME: should check the other field? 69 return lhs.FileOffset < rhs.FileOffset; 70 } 71 72 inline bool operator<(const LineEntry &E, unsigned Offset) { 73 return E.FileOffset < Offset; 74 } 75 76 inline bool operator<(unsigned Offset, const LineEntry &E) { 77 return Offset < E.FileOffset; 78 } 79 80 /// Used to hold and unique data used to represent \#line information. 81 class LineTableInfo { 82 /// Map used to assign unique IDs to filenames in \#line directives. 83 /// 84 /// This allows us to unique the filenames that 85 /// frequently reoccur and reference them with indices. FilenameIDs holds 86 /// the mapping from string -> ID, and FilenamesByID holds the mapping of ID 87 /// to string. 88 llvm::StringMap<unsigned, llvm::BumpPtrAllocator> FilenameIDs; 89 std::vector<llvm::StringMapEntry<unsigned>*> FilenamesByID; 90 91 /// Map from FileIDs to a list of line entries (sorted by the offset 92 /// at which they occur in the file). 93 std::map<FileID, std::vector<LineEntry>> LineEntries; 94 95 public: clear()96 void clear() { 97 FilenameIDs.clear(); 98 FilenamesByID.clear(); 99 LineEntries.clear(); 100 } 101 102 unsigned getLineTableFilenameID(StringRef Str); 103 getFilename(unsigned ID)104 StringRef getFilename(unsigned ID) const { 105 assert(ID < FilenamesByID.size() && "Invalid FilenameID"); 106 return FilenamesByID[ID]->getKey(); 107 } 108 getNumFilenames()109 unsigned getNumFilenames() const { return FilenamesByID.size(); } 110 111 void AddLineNote(FileID FID, unsigned Offset, 112 unsigned LineNo, int FilenameID, 113 unsigned EntryExit, SrcMgr::CharacteristicKind FileKind); 114 115 116 /// 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 using iterator = std::map<FileID, std::vector<LineEntry>>::iterator; 123 begin()124 iterator begin() { return LineEntries.begin(); } end()125 iterator end() { return LineEntries.end(); } 126 127 /// Add a new line entry that has already been encoded into 128 /// the internal representation of the line table. 129 void AddEntry(FileID FID, const std::vector<LineEntry> &Entries); 130 }; 131 132 } // namespace clang 133 134 #endif // LLVM_CLANG_BASIC_SOURCEMANAGERINTERNALS_H 135