zcov: / include/clang/Basic/SourceManager.h


Files: 1 Branches Taken: 68.3% 28 / 41
Generated: 2010-02-10 01:31 Branches Executed: 95.1% 39 / 41
Line Coverage: 100.0% 136 / 136


Programs: 71 Runs 133511


       1                 : //===--- SourceManager.h - Track and cache source files ---------*- 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                 : //  This file defines the SourceManager interface.
      11                 : //
      12                 : //===----------------------------------------------------------------------===//
      13                 : 
      14                 : #ifndef LLVM_CLANG_SOURCEMANAGER_H
      15                 : #define LLVM_CLANG_SOURCEMANAGER_H
      16                 : 
      17                 : #include "clang/Basic/SourceLocation.h"
      18                 : #include "llvm/Support/Allocator.h"
      19                 : #include "llvm/System/DataTypes.h"
      20                 : #include "llvm/ADT/DenseMap.h"
      21                 : #include <vector>
      22                 : #include <cassert>
      23                 : 
      24                 : namespace llvm {
      25                 : class MemoryBuffer;
      26                 : }
      27                 : 
      28                 : namespace clang {
      29                 : 
      30                 : class SourceManager;
      31                 : class FileManager;
      32                 : class FileEntry;
      33                 : class IdentifierTokenInfo;
      34                 : class LineTableInfo;
      35                 : 
      36                 : /// SrcMgr - Public enums and private classes that are part of the
      37                 : /// SourceManager implementation.
      38                 : ///
      39                 : namespace SrcMgr {
      40                 :   /// CharacteristicKind - This is used to represent whether a file or directory
      41                 :   /// holds normal user code, system code, or system code which is implicitly
      42                 :   /// 'extern "C"' in C++ mode.  Entire directories can be tagged with this
      43                 :   /// (this is maintained by DirectoryLookup and friends) as can specific
      44                 :   /// FileIDInfos when a #pragma system_header is seen or various other cases.
      45                 :   ///
      46                 :   enum CharacteristicKind {
      47                 :     C_User, C_System, C_ExternCSystem
      48                 :   };
      49                 : 
      50                 :   /// ContentCache - Once instance of this struct is kept for every file
      51                 :   /// loaded or used.  This object owns the MemoryBuffer object.
      52                 :   class ContentCache {
      53                 :     /// Buffer - The actual buffer containing the characters from the input
      54                 :     /// file.  This is owned by the ContentCache object.
      55                 :     mutable const llvm::MemoryBuffer *Buffer;
      56                 : 
      57                 :   public:
      58                 :     /// Reference to the file entry.  This reference does not own
      59                 :     /// the FileEntry object.  It is possible for this to be NULL if
      60                 :     /// the ContentCache encapsulates an imaginary text buffer.
      61                 :     const FileEntry *Entry;
      62                 : 
      63                 :     /// SourceLineCache - A bump pointer allocated array of offsets for each
      64                 :     /// source line.  This is lazily computed.  This is owned by the
      65                 :     /// SourceManager BumpPointerAllocator object.
      66                 :     unsigned *SourceLineCache;
      67                 : 
      68                 :     /// NumLines - The number of lines in this ContentCache.  This is only valid
      69                 :     /// if SourceLineCache is non-null.
      70                 :     unsigned NumLines;
      71                 : 
      72                 :     /// getBuffer - Returns the memory buffer for the associated content.  If
      73                 :     /// there is an error opening this buffer the first time, this manufactures
      74                 :     /// a temporary buffer and returns a non-empty error string.
      75                 :     const llvm::MemoryBuffer *getBuffer(std::string *ErrorStr = 0) const;
      76                 : 
      77                 :     /// getSize - Returns the size of the content encapsulated by this
      78                 :     ///  ContentCache. This can be the size of the source file or the size of an
      79                 :     ///  arbitrary scratch buffer.  If the ContentCache encapsulates a source
      80                 :     ///  file this size is retrieved from the file's FileEntry.
      81                 :     unsigned getSize() const;
      82                 : 
      83                 :     /// getSizeBytesMapped - Returns the number of bytes actually mapped for
      84                 :     ///  this ContentCache.  This can be 0 if the MemBuffer was not actually
      85                 :     ///  instantiated.
      86                 :     unsigned getSizeBytesMapped() const;
      87                 : 
      88             2799:     void setBuffer(const llvm::MemoryBuffer *B) {
                        0: branch 0 not taken
                     2799: branch 1 taken
      89             2799:       assert(!Buffer && "MemoryBuffer already set.");
      90             2799:       Buffer = B;
      91             2799:     }
      92                 : 
      93                 :     /// \brief Replace the existing buffer (which will be deleted)
      94                 :     /// with the given buffer.
      95                 :     void replaceBuffer(const llvm::MemoryBuffer *B);
      96                 : 
      97             5787:     ContentCache(const FileEntry *Ent = 0)
      98             5787:       : Buffer(0), Entry(Ent), SourceLineCache(0), NumLines(0) {}
      99                 : 
     100                 :     ~ContentCache();
     101                 : 
     102                 :     /// The copy ctor does not allow copies where source object has either
     103                 :     ///  a non-NULL Buffer or SourceLineCache.  Ownership of allocated memory
     104                 :     ///  is not transfered, so this is a logical error.
     105                 :     ContentCache(const ContentCache &RHS) : Buffer(0), SourceLineCache(0) {
     106                 :       Entry = RHS.Entry;
     107                 : 
     108                 :       assert (RHS.Buffer == 0 && RHS.SourceLineCache == 0
     109                 :               && "Passed ContentCache object cannot own a buffer.");
     110                 : 
     111                 :       NumLines = RHS.NumLines;
     112                 :     }
     113                 : 
     114                 :   private:
     115                 :     // Disable assignments.
     116                 :     ContentCache &operator=(const ContentCache& RHS);
     117                 :   };
     118                 : 
     119                 :   /// FileInfo - Information about a FileID, basically just the logical file
     120                 :   /// that it represents and include stack information.
     121                 :   ///
     122                 :   /// Each FileInfo has include stack information, indicating where it came
     123                 :   /// from.  This information encodes the #include chain that a token was
     124                 :   /// instantiated from.  The main include file has an invalid IncludeLoc.
     125                 :   ///
     126                 :   /// FileInfos contain a "ContentCache *", with the contents of the file.
     127                 :   ///
     128                 :   class FileInfo {
     129                 :     /// IncludeLoc - The location of the #include that brought in this file.
     130                 :     /// This is an invalid SLOC for the main file (top of the #include chain).
     131                 :     unsigned IncludeLoc;  // Really a SourceLocation
     132                 : 
     133                 :     /// Data - This contains the ContentCache* and the bits indicating the
     134                 :     /// characteristic of the file and whether it has #line info, all bitmangled
     135                 :     /// together.
     136                 :     uintptr_t Data;
     137                 :   public:
     138                 :     /// get - Return a FileInfo object.
     139                 :     static FileInfo get(SourceLocation IL, const ContentCache *Con,
     140             5865:                         CharacteristicKind FileCharacter) {
     141                 :       FileInfo X;
     142             5865:       X.IncludeLoc = IL.getRawEncoding();
     143             5865:       X.Data = (uintptr_t)Con;
                        0: branch 0 not taken
                     5865: branch 1 taken
     144             5865:       assert((X.Data & 7) == 0 &&"ContentCache pointer insufficiently aligned");
                        0: branch 0 not taken
                     5865: branch 1 taken
     145             5865:       assert((unsigned)FileCharacter < 4 && "invalid file character");
     146             5865:       X.Data |= (unsigned)FileCharacter;
     147                 :       return X;
     148                 :     }
     149                 : 
     150             9416:     SourceLocation getIncludeLoc() const {
     151             9416:       return SourceLocation::getFromRawEncoding(IncludeLoc);
     152                 :     }
     153           328416:     const ContentCache* getContentCache() const {
     154           328416:       return reinterpret_cast<const ContentCache*>(Data & ~7UL);
     155                 :     }
     156                 : 
     157                 :     /// getCharacteristic - Return whether this is a system header or not.
     158             8341:     CharacteristicKind getFileCharacteristic() const {
     159             8341:       return (CharacteristicKind)(Data & 3);
     160                 :     }
     161                 : 
     162                 :     /// hasLineDirectives - Return true if this FileID has #line directives in
     163                 :     /// it.
     164            17841:     bool hasLineDirectives() const { return (Data & 4) != 0; }
     165                 : 
     166                 :     /// setHasLineDirectives - Set the flag that indicates that this FileID has
     167                 :     /// line table entries associated with it.
     168             7620:     void setHasLineDirectives() {
     169             7620:       Data |= 4;
     170             7620:     }
     171                 :   };
     172                 : 
     173                 :   /// InstantiationInfo - Each InstantiationInfo encodes the Instantiation
     174                 :   /// location - where the token was ultimately instantiated, and the
     175                 :   /// SpellingLoc - where the actual character data for the token came from.
     176                 :   class InstantiationInfo {
     177                 :      // Really these are all SourceLocations.
     178                 : 
     179                 :     /// SpellingLoc - Where the spelling for the token can be found.
     180                 :     unsigned SpellingLoc;
     181                 : 
     182                 :     /// InstantiationLocStart/InstantiationLocEnd - In a macro expansion, these
     183                 :     /// indicate the start and end of the instantiation.  In object-like macros,
     184                 :     /// these will be the same.  In a function-like macro instantiation, the
     185                 :     /// start will be the identifier and the end will be the ')'.
     186                 :     unsigned InstantiationLocStart, InstantiationLocEnd;
     187                 :   public:
     188             3884:     SourceLocation getSpellingLoc() const {
     189             3884:       return SourceLocation::getFromRawEncoding(SpellingLoc);
     190                 :     }
     191              954:     SourceLocation getInstantiationLocStart() const {
     192              954:       return SourceLocation::getFromRawEncoding(InstantiationLocStart);
     193                 :     }
     194              322:     SourceLocation getInstantiationLocEnd() const {
     195              322:       return SourceLocation::getFromRawEncoding(InstantiationLocEnd);
     196                 :     }
     197                 : 
     198              228:     std::pair<SourceLocation,SourceLocation> getInstantiationLocRange() const {
     199                 :       return std::make_pair(getInstantiationLocStart(),
     200              228:                             getInstantiationLocEnd());
     201                 :     }
     202                 : 
     203                 :     /// get - Return a InstantiationInfo for an expansion.  IL specifies
     204                 :     /// the instantiation location (where the macro is expanded), and SL
     205                 :     /// specifies the spelling location (where the characters from the token
     206                 :     /// come from).  IL and PL can both refer to normal File SLocs or
     207                 :     /// instantiation locations.
     208                 :     static InstantiationInfo get(SourceLocation ILStart, SourceLocation ILEnd,
     209            57689:                                  SourceLocation SL) {
     210                 :       InstantiationInfo X;
     211            57689:       X.SpellingLoc = SL.getRawEncoding();
     212            57689:       X.InstantiationLocStart = ILStart.getRawEncoding();
     213            57689:       X.InstantiationLocEnd = ILEnd.getRawEncoding();
     214                 :       return X;
     215                 :     }
     216                 :   };
     217                 : 
     218                 :   /// SLocEntry - This is a discriminated union of FileInfo and
     219                 :   /// InstantiationInfo.  SourceManager keeps an array of these objects, and
     220                 :   /// they are uniquely identified by the FileID datatype.
     221                 :   class SLocEntry {
     222                 :     unsigned Offset;   // low bit is set for instantiation info.
     223                 :     union {
     224                 :       FileInfo File;
     225                 :       InstantiationInfo Instantiation;
     226                 :     };
     227                 :   public:
     228          2160322:     unsigned getOffset() const { return Offset >> 1; }
     229                 : 
     230           498354:     bool isInstantiation() const { return Offset & 1; }
     231           394886:     bool isFile() const { return !isInstantiation(); }
     232                 : 
     233           344494:     const FileInfo &getFile() const {
                   344494: branch 1 taken
                        0: branch 2 not taken
     234           344494:       assert(isFile() && "Not a file SLocEntry!");
     235           344494:       return File;
     236                 :     }
     237                 : 
     238             4744:     const InstantiationInfo &getInstantiation() const {
                     4744: branch 1 taken
                        0: branch 2 not taken
     239             4744:       assert(isInstantiation() && "Not an instantiation SLocEntry!");
     240             4744:       return Instantiation;
     241                 :     }
     242                 : 
     243             5865:     static SLocEntry get(unsigned Offset, const FileInfo &FI) {
     244                 :       SLocEntry E;
     245             5865:       E.Offset = Offset << 1;
     246             5865:       E.File = FI;
     247                 :       return E;
     248                 :     }
     249                 : 
     250            57689:     static SLocEntry get(unsigned Offset, const InstantiationInfo &II) {
     251                 :       SLocEntry E;
     252            57689:       E.Offset = (Offset << 1) | 1;
     253            57689:       E.Instantiation = II;
     254                 :       return E;
     255                 :     }
     256                 :   };
     257                 : }  // end SrcMgr namespace.
     258                 : 
     259                 : /// \brief External source of source location entries.
     260               48: class ExternalSLocEntrySource {
     261                 : public:
     262                 :   virtual ~ExternalSLocEntrySource();
     263                 : 
     264                 :   /// \brief Read the source location entry with index ID.
     265                 :   virtual void ReadSLocEntry(unsigned ID) = 0;
     266                 : };
     267                 : 
     268                 : /// SourceManager - This file handles loading and caching of source files into
     269                 : /// memory.  This object owns the MemoryBuffer objects for all of the loaded
     270                 : /// files and assigns unique FileID's for each unique #include chain.
     271                 : ///
     272                 : /// The SourceManager can be queried for information about SourceLocation
     273                 : /// objects, turning them into either spelling or instantiation locations.
     274                 : /// Spelling locations represent where the bytes corresponding to a token came
     275                 : /// from and instantiation locations represent where the location is in the
     276                 : /// user's view.  In the case of a macro expansion, for example, the spelling
     277                 : /// location indicates where the expanded token came from and the instantiation
     278                 : /// location specifies where it was expanded.
     279                 : class SourceManager {
     280                 :   mutable llvm::BumpPtrAllocator ContentCacheAlloc;
     281                 : 
     282                 :   /// FileInfos - Memoized information about all of the files tracked by this
     283                 :   /// SourceManager.  This set allows us to merge ContentCache entries based
     284                 :   /// on their FileEntry*.  All ContentCache objects will thus have unique,
     285                 :   /// non-null, FileEntry pointers.
     286                 :   llvm::DenseMap<const FileEntry*, SrcMgr::ContentCache*> FileInfos;
     287                 : 
     288                 :   /// MemBufferInfos - Information about various memory buffers that we have
     289                 :   /// read in.  All FileEntry* within the stored ContentCache objects are NULL,
     290                 :   /// as they do not refer to a file.
     291                 :   std::vector<SrcMgr::ContentCache*> MemBufferInfos;
     292                 : 
     293                 :   /// SLocEntryTable - This is an array of SLocEntry's that we have created.
     294                 :   /// FileID is an index into this vector.  This array is sorted by the offset.
     295                 :   std::vector<SrcMgr::SLocEntry> SLocEntryTable;
     296                 :   /// NextOffset - This is the next available offset that a new SLocEntry can
     297                 :   /// start at.  It is SLocEntryTable.back().getOffset()+size of back() entry.
     298                 :   unsigned NextOffset;
     299                 : 
     300                 :   /// \brief If source location entries are being lazily loaded from
     301                 :   /// an external source, this vector indicates whether the Ith source
     302                 :   /// location entry has already been loaded from the external storage.
     303                 :   std::vector<bool> SLocEntryLoaded;
     304                 : 
     305                 :   /// \brief An external source for source location entries.
     306                 :   ExternalSLocEntrySource *ExternalSLocEntries;
     307                 : 
     308                 :   /// LastFileIDLookup - This is a one-entry cache to speed up getFileID.
     309                 :   /// LastFileIDLookup records the last FileID looked up or created, because it
     310                 :   /// is very common to look up many tokens from the same file.
     311                 :   mutable FileID LastFileIDLookup;
     312                 : 
     313                 :   /// LineTable - This holds information for #line directives.  It is referenced
     314                 :   /// by indices from SLocEntryTable.
     315                 :   LineTableInfo *LineTable;
     316                 : 
     317                 :   /// LastLineNo - These ivars serve as a cache used in the getLineNumber
     318                 :   /// method which is used to speedup getLineNumber calls to nearby locations.
     319                 :   mutable FileID LastLineNoFileIDQuery;
     320                 :   mutable SrcMgr::ContentCache *LastLineNoContentCache;
     321                 :   mutable unsigned LastLineNoFilePos;
     322                 :   mutable unsigned LastLineNoResult;
     323                 : 
     324                 :   /// MainFileID - The file ID for the main source file of the translation unit.
     325                 :   FileID MainFileID;
     326                 : 
     327                 :   // Statistics for -print-stats.
     328                 :   mutable unsigned NumLinearScans, NumBinaryProbes;
     329                 : 
     330                 :   // Cache results for the isBeforeInTranslationUnit method.
     331                 :   mutable FileID LastLFIDForBeforeTUCheck;
     332                 :   mutable FileID LastRFIDForBeforeTUCheck;
     333                 :   mutable bool   LastResForBeforeTUCheck;
     334                 : 
     335                 :   // SourceManager doesn't support copy construction.
     336                 :   explicit SourceManager(const SourceManager&);
     337                 :   void operator=(const SourceManager&);
     338                 : public:
     339             2585:   SourceManager()
     340                 :     : ExternalSLocEntries(0), LineTable(0), NumLinearScans(0), 
     341             2585:       NumBinaryProbes(0) {
     342             2585:     clearIDTables();
     343             2585:   }
     344                 :   ~SourceManager();
     345                 : 
     346                 :   void clearIDTables();
     347                 : 
     348                 :   //===--------------------------------------------------------------------===//
     349                 :   // MainFileID creation and querying methods.
     350                 :   //===--------------------------------------------------------------------===//
     351                 : 
     352                 :   /// getMainFileID - Returns the FileID of the main source file.
     353            10762:   FileID getMainFileID() const { return MainFileID; }
     354                 : 
     355                 :   /// createMainFileID - Create the FileID for the main source file.
     356                 :   FileID createMainFileID(const FileEntry *SourceFile,
     357             2422:                           SourceLocation IncludePos) {
                     2422: branch 1 taken
                        0: branch 2 not taken
     358             2422:     assert(MainFileID.isInvalid() && "MainFileID already set!");
     359             2422:     MainFileID = createFileID(SourceFile, IncludePos, SrcMgr::C_User);
     360             2422:     return MainFileID;
     361                 :   }
     362                 : 
     363                 :   //===--------------------------------------------------------------------===//
     364                 :   // Methods to create new FileID's and instantiations.
     365                 :   //===--------------------------------------------------------------------===//
     366                 : 
     367                 :   /// createFileID - Create a new FileID that represents the specified file
     368                 :   /// being #included from the specified IncludePosition.  This returns 0 on
     369                 :   /// error and translates NULL into standard input.
     370                 :   /// PreallocateID should be non-zero to specify which a pre-allocated,
     371                 :   /// lazily computed source location is being filled in by this operation.
     372                 :   FileID createFileID(const FileEntry *SourceFile, SourceLocation IncludePos,
     373                 :                       SrcMgr::CharacteristicKind FileCharacter,
     374                 :                       unsigned PreallocatedID = 0,
     375             3066:                       unsigned Offset = 0) {
     376             3066:     const SrcMgr::ContentCache *IR = getOrCreateContentCache(SourceFile);
                        0: branch 0 not taken
                     3066: branch 1 taken
     377             3066:     if (IR == 0) return FileID();    // Error opening file?
     378             3066:     return createFileID(IR, IncludePos, FileCharacter, PreallocatedID, Offset);
     379                 :   }
     380                 : 
     381                 :   /// createFileIDForMemBuffer - Create a new FileID that represents the
     382                 :   /// specified memory buffer.  This does no caching of the buffer and takes
     383                 :   /// ownership of the MemoryBuffer, so only pass a MemoryBuffer to this once.
     384                 :   FileID createFileIDForMemBuffer(const llvm::MemoryBuffer *Buffer,
     385                 :                                   unsigned PreallocatedID = 0,
     386             2799:                                   unsigned Offset = 0) {
     387                 :     return createFileID(createMemBufferContentCache(Buffer), SourceLocation(),
     388             2799:                         SrcMgr::C_User, PreallocatedID, Offset);
     389                 :   }
     390                 : 
     391                 :   /// createMainFileIDForMembuffer - Create the FileID for a memory buffer
     392                 :   ///  that will represent the FileID for the main source.  One example
     393                 :   ///  of when this would be used is when the main source is read from STDIN.
     394               97:   FileID createMainFileIDForMemBuffer(const llvm::MemoryBuffer *Buffer) {
                       97: branch 1 taken
                        0: branch 2 not taken
     395               97:     assert(MainFileID.isInvalid() && "MainFileID already set!");
     396               97:     MainFileID = createFileIDForMemBuffer(Buffer);
     397               97:     return MainFileID;
     398                 :   }
     399                 : 
     400                 :   /// createInstantiationLoc - Return a new SourceLocation that encodes the fact
     401                 :   /// that a token at Loc should actually be referenced from InstantiationLoc.
     402                 :   /// TokLength is the length of the token being instantiated.
     403                 :   SourceLocation createInstantiationLoc(SourceLocation Loc,
     404                 :                                         SourceLocation InstantiationLocStart,
     405                 :                                         SourceLocation InstantiationLocEnd,
     406                 :                                         unsigned TokLength,
     407                 :                                         unsigned PreallocatedID = 0,
     408                 :                                         unsigned Offset = 0);
     409                 : 
     410                 :   /// \brief Retrieve the memory buffer associated with the given file.
     411                 :   const llvm::MemoryBuffer *getMemoryBufferForFile(const FileEntry *File);
     412                 : 
     413                 :   /// \brief Override the contents of the given source file by providing an
     414                 :   /// already-allocated buffer.
     415                 :   ///
     416                 :   /// \param SourceFile the source file whose contents will be override.
     417                 :   ///
     418                 :   /// \param Buffer the memory buffer whose contents will be used as the
     419                 :   /// data in the given source file.
     420                 :   ///
     421                 :   /// \returns true if an error occurred, false otherwise.
     422                 :   bool overrideFileContents(const FileEntry *SourceFile,
     423                 :                             const llvm::MemoryBuffer *Buffer);
     424                 : 
     425                 :   //===--------------------------------------------------------------------===//
     426                 :   // FileID manipulation methods.
     427                 :   //===--------------------------------------------------------------------===//
     428                 : 
     429                 :   /// getBuffer - Return the buffer for the specified FileID. If there is an
     430                 :   /// error opening this buffer the first time, this manufactures a temporary
     431                 :   /// buffer and returns a non-empty error string.
     432           160517:   const llvm::MemoryBuffer *getBuffer(FileID FID, std::string *Error = 0) const{
     433           160517:     return getSLocEntry(FID).getFile().getContentCache()->getBuffer(Error);
     434                 :   }
     435                 : 
     436                 :   /// getFileEntryForID - Returns the FileEntry record for the provided FileID.
     437             4591:   const FileEntry *getFileEntryForID(FileID FID) const {
     438             4591:     return getSLocEntry(FID).getFile().getContentCache()->Entry;
     439                 :   }
     440                 : 
     441                 :   /// getBufferData - Return a pointer to the start and end of the source buffer
     442                 :   /// data for the specified FileID.
     443                 :   std::pair<const char*, const char*> getBufferData(FileID FID) const;
     444                 : 
     445                 : 
     446                 :   //===--------------------------------------------------------------------===//
     447                 :   // SourceLocation manipulation methods.
     448                 :   //===--------------------------------------------------------------------===//
     449                 : 
     450                 :   /// getFileID - Return the FileID for a SourceLocation.  This is a very
     451                 :   /// hot method that is used for all SourceManager queries that start with a
     452                 :   /// SourceLocation object.  It is responsible for finding the entry in
     453                 :   /// SLocEntryTable which contains the specified location.
     454                 :   ///
     455           597779:   FileID getFileID(SourceLocation SpellingLoc) const {
     456           597779:     unsigned SLocOffset = SpellingLoc.getOffset();
     457                 : 
     458                 :     // If our one-entry cache covers this offset, just return it.
                   499067: branch 2 taken
                    98712: branch 2 taken
     459           597779:     if (isOffsetInFileID(LastFileIDLookup, SLocOffset))
     460           499067:       return LastFileIDLookup;
     461                 : 
     462            98712:     return getFileIDSlow(SLocOffset);
     463                 :   }
     464                 : 
     465                 :   /// getLocForStartOfFile - Return the source location corresponding to the
     466                 :   /// first byte of the specified file.
     467            24194:   SourceLocation getLocForStartOfFile(FileID FID) const {
                    24194: branch 1 taken
                        0: branch 2 not taken
     468            24194:     assert(FID.ID < SLocEntryTable.size() && "FileID out of range");
                    24194: branch 2 taken
                        0: branch 3 not taken
     469            24194:     assert(getSLocEntry(FID).isFile() && "FileID is not a file");
     470            24194:     unsigned FileOffset = getSLocEntry(FID).getOffset();
     471            24194:     return SourceLocation::getFileLoc(FileOffset);
     472                 :   }
     473                 : 
     474                 :   /// getInstantiationLoc - Given a SourceLocation object, return the
     475                 :   /// instantiation location referenced by the ID.
     476           145240:   SourceLocation getInstantiationLoc(SourceLocation Loc) const {
     477                 :     // Handle the non-mapped case inline, defer to out of line code to handle
     478                 :     // instantiations.
                   145172: branch 1 taken
                       68: branch 2 taken
     479           145240:     if (Loc.isFileID()) return Loc;
     480               68:     return getInstantiationLocSlowCase(Loc);
     481                 :   }
     482                 : 
     483                 :   /// getImmediateInstantiationRange - Loc is required to be an instantiation
     484                 :   /// location.  Return the start/end of the instantiation information.
     485                 :   std::pair<SourceLocation,SourceLocation>
     486                 :   getImmediateInstantiationRange(SourceLocation Loc) const;
     487                 : 
     488                 :   /// getInstantiationRange - Given a SourceLocation object, return the
     489                 :   /// range of tokens covered by the instantiation in the ultimate file.
     490                 :   std::pair<SourceLocation,SourceLocation>
     491                 :   getInstantiationRange(SourceLocation Loc) const;
     492                 : 
     493                 : 
     494                 :   /// getSpellingLoc - Given a SourceLocation object, return the spelling
     495                 :   /// location referenced by the ID.  This is the place where the characters
     496                 :   /// that make up the lexed token can be found.
     497             5834:   SourceLocation getSpellingLoc(SourceLocation Loc) const {
     498                 :     // Handle the non-mapped case inline, defer to out of line code to handle
     499                 :     // instantiations.
                      584: branch 2 taken
                        0: branch 2 not taken
     500             5834:     if (Loc.isFileID()) return Loc;
     501              584:     return getSpellingLocSlowCase(Loc);
     502                 :   }
     503                 : 
     504                 :   /// getImmediateSpellingLoc - Given a SourceLocation object, return the
     505                 :   /// spelling location referenced by the ID.  This is the first level down
     506                 :   /// towards the place where the characters that make up the lexed token can be
     507                 :   /// found.  This should not generally be used by clients.
     508                 :   SourceLocation getImmediateSpellingLoc(SourceLocation Loc) const;
     509                 : 
     510                 :   /// getDecomposedLoc - Decompose the specified location into a raw FileID +
     511                 :   /// Offset pair.  The first element is the FileID, the second is the
     512                 :   /// offset from the start of the buffer of the location.
     513           394719:   std::pair<FileID, unsigned> getDecomposedLoc(SourceLocation Loc) const {
     514           394719:     FileID FID = getFileID(Loc);
     515           394719:     return std::make_pair(FID, Loc.getOffset()-getSLocEntry(FID).getOffset());
     516                 :   }
     517                 : 
     518                 :   /// getDecomposedInstantiationLoc - Decompose the specified location into a
     519                 :   /// raw FileID + Offset pair.  If the location is an instantiation record,
     520                 :   /// walk through it until we find the final location instantiated.
     521                 :   std::pair<FileID, unsigned>
     522            56923:   getDecomposedInstantiationLoc(SourceLocation Loc) const {
     523            56923:     FileID FID = getFileID(Loc);
     524            56923:     const SrcMgr::SLocEntry *E = &getSLocEntry(FID);
     525                 : 
     526            56923:     unsigned Offset = Loc.getOffset()-E->getOffset();
                    56398: branch 1 taken
                      525: branch 2 taken
     527            56923:     if (Loc.isFileID())
     528            56398:       return std::make_pair(FID, Offset);
     529                 : 
     530              525:     return getDecomposedInstantiationLocSlowCase(E, Offset);
     531                 :   }
     532                 : 
     533                 :   /// getDecomposedSpellingLoc - Decompose the specified location into a raw
     534                 :   /// FileID + Offset pair.  If the location is an instantiation record, walk
     535                 :   /// through it until we find its spelling record.
     536                 :   std::pair<FileID, unsigned>
     537           136419:   getDecomposedSpellingLoc(SourceLocation Loc) const {
     538           136419:     FileID FID = getFileID(Loc);
     539           136419:     const SrcMgr::SLocEntry *E = &getSLocEntry(FID);
     540                 : 
     541           136419:     unsigned Offset = Loc.getOffset()-E->getOffset();
     542           136419:     if (Loc.isFileID())
     543           134248:       return std::make_pair(FID, Offset);
     544             2171:     return getDecomposedSpellingLocSlowCase(E, Offset);
     545                 :   }
     546                 : 
     547                 :   /// getFileOffset - This method returns the offset from the start
     548                 :   /// of the file that the specified SourceLocation represents. This is not very
     549                 :   /// meaningful for a macro ID.
     550              169:   unsigned getFileOffset(SourceLocation SpellingLoc) const {
     551              169:     return getDecomposedLoc(SpellingLoc).second;
     552                 :   }
     553                 : 
     554                 : 
     555                 :   //===--------------------------------------------------------------------===//
     556                 :   // Queries about the code at a SourceLocation.
     557                 :   //===--------------------------------------------------------------------===//
     558                 : 
     559                 :   /// getCharacterData - Return a pointer to the start of the specified location
     560                 :   /// in the appropriate spelling MemoryBuffer.
     561                 :   const char *getCharacterData(SourceLocation SL) const;
     562                 : 
     563                 :   /// getColumnNumber - Return the column # for the specified file position.
     564                 :   /// This is significantly cheaper to compute than the line number.  This
     565                 :   /// returns zero if the column number isn't known.  This may only be called on
     566                 :   /// a file sloc, so you must choose a spelling or instantiation location
     567                 :   /// before calling this method.
     568                 :   unsigned getColumnNumber(FileID FID, unsigned FilePos) const;
     569                 :   unsigned getSpellingColumnNumber(SourceLocation Loc) const;
     570                 :   unsigned getInstantiationColumnNumber(SourceLocation Loc) const;
     571                 : 
     572                 : 
     573                 :   /// getLineNumber - Given a SourceLocation, return the spelling line number
     574                 :   /// for the position indicated.  This requires building and caching a table of
     575                 :   /// line offsets for the MemoryBuffer, so this is not cheap: use only when
     576                 :   /// about to emit a diagnostic.
     577                 :   unsigned getLineNumber(FileID FID, unsigned FilePos) const;
     578                 : 
     579                 :   unsigned getInstantiationLineNumber(SourceLocation Loc) const;
     580                 :   unsigned getSpellingLineNumber(SourceLocation Loc) const;
     581                 : 
     582                 :   /// Return the filename or buffer identifier of the buffer the location is in.
     583                 :   /// Note that this name does not respect #line directives.  Use getPresumedLoc
     584                 :   /// for normal clients.
     585                 :   const char *getBufferName(SourceLocation Loc) const;
     586                 : 
     587                 :   /// getFileCharacteristic - return the file characteristic of the specified
     588                 :   /// source location, indicating whether this is a normal file, a system
     589                 :   /// header, or an "implicit extern C" system header.
     590                 :   ///
     591                 :   /// This state can be modified with flags on GNU linemarker directives like:
     592                 :   ///   # 4 "foo.h" 3
     593                 :   /// which changes all source locations in the current file after that to be
     594                 :   /// considered to be from a system header.
     595                 :   SrcMgr::CharacteristicKind getFileCharacteristic(SourceLocation Loc) const;
     596                 : 
     597                 :   /// getPresumedLoc - This method returns the "presumed" location of a
     598                 :   /// SourceLocation specifies.  A "presumed location" can be modified by #line
     599                 :   /// or GNU line marker directives.  This provides a view on the data that a
     600                 :   /// user should see in diagnostics, for example.
     601                 :   ///
     602                 :   /// Note that a presumed location is always given as the instantiation point
     603                 :   /// of an instantiation location, not at the spelling location.
     604                 :   PresumedLoc getPresumedLoc(SourceLocation Loc) const;
     605                 : 
     606                 :   /// isFromSameFile - Returns true if both SourceLocations correspond to
     607                 :   ///  the same file.
     608               51:   bool isFromSameFile(SourceLocation Loc1, SourceLocation Loc2) const {
     609               51:     return getFileID(Loc1) == getFileID(Loc2);
     610                 :   }
     611                 : 
     612                 :   /// isFromMainFile - Returns true if the file of provided SourceLocation is
     613                 :   ///   the main file.
     614             2958:   bool isFromMainFile(SourceLocation Loc) const {
     615             2958:     return getFileID(Loc) == getMainFileID();
     616                 :   }
     617                 : 
     618                 :   /// isInSystemHeader - Returns if a SourceLocation is in a system header.
     619             4617:   bool isInSystemHeader(SourceLocation Loc) const {
     620             4617:     return getFileCharacteristic(Loc) != SrcMgr::C_User;
     621                 :   }
     622                 : 
     623                 :   /// isInExternCSystemHeader - Returns if a SourceLocation is in an "extern C"
     624                 :   /// system header.
     625             2503:   bool isInExternCSystemHeader(SourceLocation Loc) const {
     626             2503:     return getFileCharacteristic(Loc) == SrcMgr::C_ExternCSystem;
     627                 :   }
     628                 : 
     629                 :   //===--------------------------------------------------------------------===//
     630                 :   // Line Table Manipulation Routines
     631                 :   //===--------------------------------------------------------------------===//
     632                 : 
     633                 :   /// getLineTableFilenameID - Return the uniqued ID for the specified filename.
     634                 :   ///
     635                 :   unsigned getLineTableFilenameID(const char *Ptr, unsigned Len);
     636                 : 
     637                 :   /// AddLineNote - Add a line note to the line table for the FileID and offset
     638                 :   /// specified by Loc.  If FilenameID is -1, it is considered to be
     639                 :   /// unspecified.
     640                 :   void AddLineNote(SourceLocation Loc, unsigned LineNo, int FilenameID);
     641                 :   void AddLineNote(SourceLocation Loc, unsigned LineNo, int FilenameID,
     642                 :                    bool IsFileEntry, bool IsFileExit,
     643                 :                    bool IsSystemHeader, bool IsExternCHeader);
     644                 : 
     645                 :   /// \brief Determine if the source manager has a line table.
     646               44:   bool hasLineTable() const { return LineTable != 0; }
     647                 : 
     648                 :   /// \brief Retrieve the stored line table.
     649                 :   LineTableInfo &getLineTable();
     650                 : 
     651                 :   //===--------------------------------------------------------------------===//
     652                 :   // Other miscellaneous methods.
     653                 :   //===--------------------------------------------------------------------===//
     654                 : 
     655                 :   /// \brief Get the source location for the given file:line:col triplet.
     656                 :   ///
     657                 :   /// If the source file is included multiple times, the source location will
     658                 :   /// be based upon the first inclusion.
     659                 :   SourceLocation getLocation(const FileEntry *SourceFile,
     660                 :                              unsigned Line, unsigned Col) const;
     661                 : 
     662                 :   /// \brief Determines the order of 2 source locations in the translation unit.
     663                 :   ///
     664                 :   /// \returns true if LHS source location comes before RHS, false otherwise.
     665                 :   bool isBeforeInTranslationUnit(SourceLocation LHS, SourceLocation RHS) const;
     666                 : 
     667                 :   // Iterators over FileInfos.
     668                 :   typedef llvm::DenseMap<const FileEntry*, SrcMgr::ContentCache*>
     669                 :       ::const_iterator fileinfo_iterator;
     670                3:   fileinfo_iterator fileinfo_begin() const { return FileInfos.begin(); }
     671                3:   fileinfo_iterator fileinfo_end() const { return FileInfos.end(); }
     672               82:   bool hasFileInfo(const FileEntry *File) const {
     673               82:     return FileInfos.find(File) != FileInfos.end();
     674                 :   }
     675                 : 
     676                 :   /// PrintStats - Print statistics to stderr.
     677                 :   ///
     678                 :   void PrintStats() const;
     679                 : 
     680            12992:   unsigned sloc_entry_size() const { return SLocEntryTable.size(); }
     681                 :   
     682                 :   // FIXME: Exposing this is a little gross; what we want is a good way
     683                 :   //  to iterate the entries that were not defined in a PCH file (or
     684                 :   //  any other external source).
     685                1:   unsigned sloc_loaded_entry_size() const { return SLocEntryLoaded.size(); }
     686                 : 
     687          2309214:   const SrcMgr::SLocEntry &getSLocEntry(unsigned ID) const {
                  2309214: branch 1 taken
                        0: branch 2 not taken
     688          2309214:     assert(ID < SLocEntryTable.size() && "Invalid id");
                  1716527: branch 0 taken
                   592687: branch 1 taken
                  1714986: branch 3 taken
                     1541: branch 4 taken
                       39: branch 6 taken
                  1714947: branch 7 taken
                       39: branch 8 taken
                  2309175: branch 9 taken
     689          4025741:     if (ExternalSLocEntries &&
     690                 :         ID < SLocEntryLoaded.size() &&
     691                 :         !SLocEntryLoaded[ID])
     692               39:       ExternalSLocEntries->ReadSLocEntry(ID);
     693          2309214:     return SLocEntryTable[ID];
     694                 :   }
     695                 :   
     696          2283124:   const SrcMgr::SLocEntry &getSLocEntry(FileID FID) const {    
     697          2283124:     return getSLocEntry(FID.ID);
     698                 :   }
     699                 : 
     700              138:   unsigned getNextOffset() const { return NextOffset; }
     701                 : 
     702                 :   /// \brief Preallocate some number of source location entries, which
     703                 :   /// will be loaded as needed from the given external source.
     704                 :   void PreallocateSLocEntries(ExternalSLocEntrySource *Source,
     705                 :                               unsigned NumSLocEntries,
     706                 :                               unsigned NextOffset);
     707                 : 
     708                 :   /// \brief Clear out any preallocated source location entries that
     709                 :   /// haven't already been loaded.
     710                 :   void ClearPreallocatedSLocEntries();
     711                 : 
     712                 : private:
     713                 :   /// isOffsetInFileID - Return true if the specified FileID contains the
     714                 :   /// specified SourceLocation offset.  This is a very hot method.
     715           630616:   inline bool isOffsetInFileID(FileID FID, unsigned SLocOffset) const {
     716           630616:     const SrcMgr::SLocEntry &Entry = getSLocEntry(FID);
     717                 :     // If the entry is after the offset, it can't contain it.
                        0: branch 2 not taken
     718           630616:     if (SLocOffset < Entry.getOffset()) return false;
     719                 : 
     720                 :     // If this is the last entry than it does.  Otherwise, the entry after it
     721                 :     // has to not include it.
                    89017: branch 1 taken
                   490477: branch 2 taken
     722           579494:     if (FID.ID+1 == SLocEntryTable.size()) return true;
     723                 : 
     724           490477:     return SLocOffset < getSLocEntry(FileID::get(FID.ID+1)).getOffset();
     725                 :   }
     726                 : 
     727                 :   /// createFileID - Create a new fileID for the specified ContentCache and
     728                 :   ///  include position.  This works regardless of whether the ContentCache
     729                 :   ///  corresponds to a file or some other input source.
     730                 :   FileID createFileID(const SrcMgr::ContentCache* File,
     731                 :                       SourceLocation IncludePos,
     732                 :                       SrcMgr::CharacteristicKind DirCharacter,
     733                 :                       unsigned PreallocatedID = 0,
     734                 :                       unsigned Offset = 0);
     735                 : 
     736                 :   const SrcMgr::ContentCache *
     737                 :     getOrCreateContentCache(const FileEntry *SourceFile);
     738                 : 
     739                 :   /// createMemBufferContentCache - Create a new ContentCache for the specified
     740                 :   ///  memory buffer.
     741                 :   const SrcMgr::ContentCache*
     742                 :   createMemBufferContentCache(const llvm::MemoryBuffer *Buf);
     743                 : 
     744                 :   FileID getFileIDSlow(unsigned SLocOffset) const;
     745                 : 
     746                 :   SourceLocation getInstantiationLocSlowCase(SourceLocation Loc) const;
     747                 :   SourceLocation getSpellingLocSlowCase(SourceLocation Loc) const;
     748                 : 
     749                 :   std::pair<FileID, unsigned>
     750                 :   getDecomposedInstantiationLocSlowCase(const SrcMgr::SLocEntry *E,
     751                 :                                         unsigned Offset) const;
     752                 :   std::pair<FileID, unsigned>
     753                 :   getDecomposedSpellingLocSlowCase(const SrcMgr::SLocEntry *E,
     754                 :                                    unsigned Offset) const;
     755                 : };
     756                 : 
     757                 : 
     758                 : }  // end namespace clang
     759                 : 
     760                 : #endif

Generated: 2010-02-10 01:31 by zcov