Home | History | Annotate | Line # | Download | only in Basic
      1 //===- SourceManagerInternals.h - SourceManager Internals -------*- C++ -*-===//
      2 //
      3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
      4 // See https://llvm.org/LICENSE.txt for license information.
      5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
      6 //
      7 //===----------------------------------------------------------------------===//
      8 //
      9 /// \file
     10 /// Defines implementation details of the clang::SourceManager class.
     11 //
     12 //===----------------------------------------------------------------------===//
     13 
     14 #ifndef LLVM_CLANG_BASIC_SOURCEMANAGERINTERNALS_H
     15 #define LLVM_CLANG_BASIC_SOURCEMANAGERINTERNALS_H
     16 
     17 #include "clang/Basic/SourceLocation.h"
     18 #include "clang/Basic/SourceManager.h"
     19 #include "llvm/ADT/StringMap.h"
     20 #include "llvm/ADT/StringRef.h"
     21 #include "llvm/Support/Allocator.h"
     22 #include <cassert>
     23 #include <map>
     24 #include <vector>
     25 
     26 namespace clang {
     27 
     28 //===----------------------------------------------------------------------===//
     29 // Line Table Implementation
     30 //===----------------------------------------------------------------------===//
     31 
     32 struct LineEntry {
     33   /// The offset in this file that the line entry occurs at.
     34   unsigned FileOffset;
     35 
     36   /// The presumed line number of this line entry: \#line 4.
     37   unsigned LineNo;
     38 
     39   /// The ID of the filename identified by this line entry:
     40   /// \#line 4 "foo.c".  This is -1 if not specified.
     41   int FilenameID;
     42 
     43   /// Set the 0 if no flags, 1 if a system header,
     44   SrcMgr::CharacteristicKind FileKind;
     45 
     46   /// The offset of the virtual include stack location,
     47   /// which is manipulated by GNU linemarker directives.
     48   ///
     49   /// If this is 0 then there is no virtual \#includer.
     50   unsigned IncludeOffset;
     51 
     52   static LineEntry get(unsigned Offs, unsigned Line, int Filename,
     53                        SrcMgr::CharacteristicKind FileKind,
     54                        unsigned IncludeOffset) {
     55     LineEntry E;
     56     E.FileOffset = Offs;
     57     E.LineNo = Line;
     58     E.FilenameID = Filename;
     59     E.FileKind = FileKind;
     60     E.IncludeOffset = IncludeOffset;
     61     return E;
     62   }
     63 };
     64 
     65 // needed for FindNearestLineEntry (upper_bound of LineEntry)
     66 inline bool operator<(const LineEntry &lhs, const LineEntry &rhs) {
     67   // FIXME: should check the other field?
     68   return lhs.FileOffset < rhs.FileOffset;
     69 }
     70 
     71 inline bool operator<(const LineEntry &E, unsigned Offset) {
     72   return E.FileOffset < Offset;
     73 }
     74 
     75 inline bool operator<(unsigned Offset, const LineEntry &E) {
     76   return Offset < E.FileOffset;
     77 }
     78 
     79 /// Used to hold and unique data used to represent \#line information.
     80 class LineTableInfo {
     81   /// Map used to assign unique IDs to filenames in \#line directives.
     82   ///
     83   /// This allows us to unique the filenames that
     84   /// frequently reoccur and reference them with indices.  FilenameIDs holds
     85   /// the mapping from string -> ID, and FilenamesByID holds the mapping of ID
     86   /// to string.
     87   llvm::StringMap<unsigned, llvm::BumpPtrAllocator> FilenameIDs;
     88   std::vector<llvm::StringMapEntry<unsigned>*> FilenamesByID;
     89 
     90   /// Map from FileIDs to a list of line entries (sorted by the offset
     91   /// at which they occur in the file).
     92   std::map<FileID, std::vector<LineEntry>> LineEntries;
     93 
     94 public:
     95   void clear() {
     96     FilenameIDs.clear();
     97     FilenamesByID.clear();
     98     LineEntries.clear();
     99   }
    100 
    101   unsigned getLineTableFilenameID(StringRef Str);
    102 
    103   StringRef getFilename(unsigned ID) const {
    104     assert(ID < FilenamesByID.size() && "Invalid FilenameID");
    105     return FilenamesByID[ID]->getKey();
    106   }
    107 
    108   unsigned getNumFilenames() const { return FilenamesByID.size(); }
    109 
    110   void AddLineNote(FileID FID, unsigned Offset,
    111                    unsigned LineNo, int FilenameID,
    112                    unsigned EntryExit, SrcMgr::CharacteristicKind FileKind);
    113 
    114 
    115   /// Find the line entry nearest to FID that is before it.
    116   ///
    117   /// If there is no line entry before \p Offset in \p FID, returns null.
    118   const LineEntry *FindNearestLineEntry(FileID FID, unsigned Offset);
    119 
    120   // Low-level access
    121   using iterator = std::map<FileID, std::vector<LineEntry>>::iterator;
    122 
    123   iterator begin() { return LineEntries.begin(); }
    124   iterator end() { return LineEntries.end(); }
    125 
    126   /// 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 } // namespace clang
    132 
    133 #endif // LLVM_CLANG_BASIC_SOURCEMANAGERINTERNALS_H
    134