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 23namespace clang { 24 25//===----------------------------------------------------------------------===// 26// Line Table Implementation 27//===----------------------------------------------------------------------===// 28 29struct 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 49 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) 63inline bool operator<(const LineEntry &lhs, const LineEntry &rhs) { 64 // FIXME: should check the other field? 65 return lhs.FileOffset < rhs.FileOffset; 66} 67 68inline bool operator<(const LineEntry &E, unsigned Offset) { 69 return E.FileOffset < Offset; 70} 71 72inline 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. 77class 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; 90public: 91 LineTableInfo() { 92 } 93 94 void clear() { 95 FilenameIDs.clear(); 96 FilenamesByID.clear(); 97 LineEntries.clear(); 98 } 99 100 ~LineTableInfo() {} 101 102 unsigned getLineTableFilenameID(StringRef Str); 103 const char *getFilename(unsigned ID) const { 104 assert(ID < FilenamesByID.size() && "Invalid FilenameID"); 105 return FilenamesByID[ID]->getKeyData(); 106 } 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; 123 iterator begin() { return LineEntries.begin(); } 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