clang API Documentation

SourceManagerInternals.h
Go to the documentation of this file.
00001 //===--- SourceManagerInternals.h - SourceManager Internals -----*- C++ -*-===//
00002 //
00003 //                     The LLVM Compiler Infrastructure
00004 //
00005 // This file is distributed under the University of Illinois Open Source
00006 // License. See LICENSE.TXT for details.
00007 //
00008 //===----------------------------------------------------------------------===//
00009 ///
00010 /// \file
00011 /// \brief Defines implementation details of the clang::SourceManager class.
00012 ///
00013 //===----------------------------------------------------------------------===//
00014 
00015 #ifndef LLVM_CLANG_BASIC_SOURCEMANAGERINTERNALS_H
00016 #define LLVM_CLANG_BASIC_SOURCEMANAGERINTERNALS_H
00017 
00018 #include "clang/Basic/SourceLocation.h"
00019 #include "clang/Basic/SourceManager.h"
00020 #include "llvm/ADT/StringMap.h"
00021 #include <map>
00022 
00023 namespace clang {
00024 
00025 //===----------------------------------------------------------------------===//
00026 // Line Table Implementation
00027 //===----------------------------------------------------------------------===//
00028 
00029 struct LineEntry {
00030   /// \brief The offset in this file that the line entry occurs at.
00031   unsigned FileOffset;
00032 
00033   /// \brief The presumed line number of this line entry: \#line 4.
00034   unsigned LineNo;
00035 
00036   /// \brief The ID of the filename identified by this line entry:
00037   /// \#line 4 "foo.c".  This is -1 if not specified.
00038   int FilenameID;
00039 
00040   /// \brief Set the 0 if no flags, 1 if a system header,
00041   SrcMgr::CharacteristicKind FileKind;
00042 
00043   /// \brief The offset of the virtual include stack location,
00044   /// which is manipulated by GNU linemarker directives.
00045   ///
00046   /// If this is 0 then there is no virtual \#includer.
00047   unsigned IncludeOffset;
00048 
00049   static LineEntry get(unsigned Offs, unsigned Line, int Filename,
00050                        SrcMgr::CharacteristicKind FileKind,
00051                        unsigned IncludeOffset) {
00052     LineEntry E;
00053     E.FileOffset = Offs;
00054     E.LineNo = Line;
00055     E.FilenameID = Filename;
00056     E.FileKind = FileKind;
00057     E.IncludeOffset = IncludeOffset;
00058     return E;
00059   }
00060 };
00061 
00062 // needed for FindNearestLineEntry (upper_bound of LineEntry)
00063 inline bool operator<(const LineEntry &lhs, const LineEntry &rhs) {
00064   // FIXME: should check the other field?
00065   return lhs.FileOffset < rhs.FileOffset;
00066 }
00067 
00068 inline bool operator<(const LineEntry &E, unsigned Offset) {
00069   return E.FileOffset < Offset;
00070 }
00071 
00072 inline bool operator<(unsigned Offset, const LineEntry &E) {
00073   return Offset < E.FileOffset;
00074 }
00075 
00076 /// \brief Used to hold and unique data used to represent \#line information.
00077 class LineTableInfo {
00078   /// \brief Map used to assign unique IDs to filenames in \#line directives. 
00079   ///
00080   /// This allows us to unique the filenames that
00081   /// frequently reoccur and reference them with indices.  FilenameIDs holds
00082   /// the mapping from string -> ID, and FilenamesByID holds the mapping of ID
00083   /// to string.
00084   llvm::StringMap<unsigned, llvm::BumpPtrAllocator> FilenameIDs;
00085   std::vector<llvm::StringMapEntry<unsigned>*> FilenamesByID;
00086 
00087   /// \brief Map from FileIDs to a list of line entries (sorted by the offset
00088   /// at which they occur in the file).
00089   std::map<FileID, std::vector<LineEntry> > LineEntries;
00090 public:
00091   LineTableInfo() {
00092   }
00093 
00094   void clear() {
00095     FilenameIDs.clear();
00096     FilenamesByID.clear();
00097     LineEntries.clear();
00098   }
00099 
00100   ~LineTableInfo() {}
00101 
00102   unsigned getLineTableFilenameID(StringRef Str);
00103   const char *getFilename(unsigned ID) const {
00104     assert(ID < FilenamesByID.size() && "Invalid FilenameID");
00105     return FilenamesByID[ID]->getKeyData();
00106   }
00107   unsigned getNumFilenames() const { return FilenamesByID.size(); }
00108 
00109   void AddLineNote(FileID FID, unsigned Offset,
00110                    unsigned LineNo, int FilenameID);
00111   void AddLineNote(FileID FID, unsigned Offset,
00112                    unsigned LineNo, int FilenameID,
00113                    unsigned EntryExit, SrcMgr::CharacteristicKind FileKind);
00114 
00115 
00116   /// \brief Find the line entry nearest to FID that is before it.
00117   ///
00118   /// If there is no line entry before \p Offset in \p FID, returns null.
00119   const LineEntry *FindNearestLineEntry(FileID FID, unsigned Offset);
00120 
00121   // Low-level access
00122   typedef std::map<FileID, std::vector<LineEntry> >::iterator iterator;
00123   iterator begin() { return LineEntries.begin(); }
00124   iterator end() { return LineEntries.end(); }
00125 
00126   /// \brief Add a new line entry that has already been encoded into
00127   /// the internal representation of the line table.
00128   void AddEntry(FileID FID, const std::vector<LineEntry> &Entries);
00129 };
00130 
00131 } // end namespace clang
00132 
00133 #endif