Home | History | Annotate | Download | only in Basic
      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 
     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)
     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:
     91   void clear() {
     92     FilenameIDs.clear();
     93     FilenamesByID.clear();
     94     LineEntries.clear();
     95   }
     96 
     97   unsigned getLineTableFilenameID(StringRef Str);
     98   const char *getFilename(unsigned ID) const {
     99     assert(ID < FilenamesByID.size() && "Invalid FilenameID");
    100     return FilenamesByID[ID]->getKeyData();
    101   }
    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;
    118   iterator begin() { return LineEntries.begin(); }
    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