]> granicus.if.org Git - clang/blobdiff - include/clang/Basic/SourceManager.h
Header guard canonicalization, clang part.
[clang] / include / clang / Basic / SourceManager.h
index c2bf2c5da01e1750fea443ee2a64d048d6004aa2..484765b41c59f5086304662bcf4eb3457e458763 100644 (file)
@@ -32,8 +32,8 @@
 ///
 //===----------------------------------------------------------------------===//
 
-#ifndef LLVM_CLANG_SOURCEMANAGER_H
-#define LLVM_CLANG_SOURCEMANAGER_H
+#ifndef LLVM_CLANG_BASIC_SOURCEMANAGER_H
+#define LLVM_CLANG_BASIC_SOURCEMANAGER_H
 
 #include "clang/Basic/FileManager.h"
 #include "clang/Basic/LLVM.h"
 #include "llvm/ADT/DenseMap.h"
 #include "llvm/ADT/DenseSet.h"
 #include "llvm/ADT/IntrusiveRefCntPtr.h"
-#include "llvm/ADT/OwningPtr.h"
 #include "llvm/ADT/PointerIntPair.h"
 #include "llvm/ADT/PointerUnion.h"
+#include "llvm/Support/AlignOf.h"
 #include "llvm/Support/Allocator.h"
 #include "llvm/Support/DataTypes.h"
 #include "llvm/Support/MemoryBuffer.h"
 #include <cassert>
 #include <map>
+#include <memory>
 #include <vector>
 
 namespace clang {
@@ -89,12 +90,21 @@ namespace SrcMgr {
       DoNotFreeFlag = 0x02
     };
 
+    // Note that the first member of this class is an aligned character buffer
+    // to ensure that this class has an alignment of 8 bytes. This wastes
+    // 8 bytes for every ContentCache object, but each of these corresponds to
+    // a file loaded into memory, so the 8 bytes doesn't seem terribly
+    // important. It is quite awkward to fit this aligner into any other part
+    // of the class due to the lack of portable ways to combine it with other
+    // members.
+    llvm::AlignedCharArray<8, 1> NonceAligner;
+
     /// \brief The actual buffer containing the characters from the input
     /// file.
     ///
     /// This is owned by the ContentCache object.  The bits indicate
     /// whether the buffer is invalid.
-    mutable llvm::PointerIntPair<const llvm::MemoryBuffer *, 2> Buffer;
+    mutable llvm::PointerIntPair<llvm::MemoryBuffer *, 2> Buffer;
 
   public:
     /// \brief Reference to the file entry representing this ContentCache.
@@ -133,14 +143,16 @@ namespace SrcMgr {
     /// file considered as a system one.
     unsigned IsSystemFile : 1;
     
-    ContentCache(const FileEntry *Ent = 0)
-      : Buffer(0, false), OrigEntry(Ent), ContentsEntry(Ent),
-        SourceLineCache(0), NumLines(0), BufferOverridden(false),
-        IsSystemFile(false) {}
+    ContentCache(const FileEntry *Ent = nullptr)
+      : Buffer(nullptr, false), OrigEntry(Ent), ContentsEntry(Ent),
+        SourceLineCache(nullptr), NumLines(0), BufferOverridden(false),
+        IsSystemFile(false) {
+      (void)NonceAligner; // Silence warnings about unused member.
+    }
     
     ContentCache(const FileEntry *Ent, const FileEntry *contentEnt)
-      : Buffer(0, false), OrigEntry(Ent), ContentsEntry(contentEnt),
-        SourceLineCache(0), NumLines(0), BufferOverridden(false),
+      : Buffer(nullptr, false), OrigEntry(Ent), ContentsEntry(contentEnt),
+        SourceLineCache(nullptr), NumLines(0), BufferOverridden(false),
         IsSystemFile(false) {}
     
     ~ContentCache();
@@ -149,15 +161,15 @@ namespace SrcMgr {
     /// a non-NULL Buffer or SourceLineCache.  Ownership of allocated memory
     /// is not transferred, so this is a logical error.
     ContentCache(const ContentCache &RHS)
-      : Buffer(0, false), SourceLineCache(0), BufferOverridden(false),
-        IsSystemFile(false)
-    {
+      : Buffer(nullptr, false), SourceLineCache(nullptr),
+        BufferOverridden(false), IsSystemFile(false) {
       OrigEntry = RHS.OrigEntry;
       ContentsEntry = RHS.ContentsEntry;
-      
-      assert (RHS.Buffer.getPointer() == 0 && RHS.SourceLineCache == 0 &&
-              "Passed ContentCache object cannot own a buffer.");
-      
+
+      assert(RHS.Buffer.getPointer() == nullptr &&
+             RHS.SourceLineCache == nullptr &&
+             "Passed ContentCache object cannot own a buffer.");
+
       NumLines = RHS.NumLines;
     }
 
@@ -170,10 +182,10 @@ namespace SrcMgr {
     ///   will be emitted at.
     ///
     /// \param Invalid If non-NULL, will be set \c true if an error occurred.
-    const llvm::MemoryBuffer *getBuffer(DiagnosticsEngine &Diag,
-                                        const SourceManager &SM,
-                                        SourceLocation Loc = SourceLocation(),
-                                        bool *Invalid = 0) const;
+    llvm::MemoryBuffer *getBuffer(DiagnosticsEngine &Diag,
+                                  const SourceManager &SM,
+                                  SourceLocation Loc = SourceLocation(),
+                                  bool *Invalid = nullptr) const;
 
     /// \brief Returns the size of the content encapsulated by this
     /// ContentCache.
@@ -193,7 +205,7 @@ namespace SrcMgr {
     /// this content cache.  This is used for performance analysis.
     llvm::MemoryBuffer::BufferKind getMemoryBufferKind() const;
 
-    void setBuffer(const llvm::MemoryBuffer *B) {
+    void setBuffer(llvm::MemoryBuffer *B) {
       assert(!Buffer.getPointer() && "MemoryBuffer already set.");
       Buffer.setPointer(B);
       Buffer.setInt(false);
@@ -201,13 +213,11 @@ namespace SrcMgr {
 
     /// \brief Get the underlying buffer, returning NULL if the buffer is not
     /// yet available.
-    const llvm::MemoryBuffer *getRawBuffer() const {
-      return Buffer.getPointer();
-    }
+    llvm::MemoryBuffer *getRawBuffer() const { return Buffer.getPointer(); }
 
     /// \brief Replace the existing buffer (which will be deleted)
     /// with the given buffer.
-    void replaceBuffer(const llvm::MemoryBuffer *B, bool DoNotFree = false);
+    void replaceBuffer(llvm::MemoryBuffer *B, bool DoNotFree = false);
 
     /// \brief Determine whether the buffer itself is invalid.
     bool isBufferInvalid() const {
@@ -224,6 +234,11 @@ namespace SrcMgr {
     ContentCache &operator=(const ContentCache& RHS) LLVM_DELETED_FUNCTION;
   };
 
+  // Assert that the \c ContentCache objects will always be 8-byte aligned so
+  // that we can pack 3 bits of integer into pointers to such objects.
+  static_assert(llvm::AlignOf<ContentCache>::Alignment >= 8,
+                "ContentCache must be 8-byte aligned.");
+
   /// \brief Information about a FileID, basically just the logical file
   /// that it represents and include stack information.
   ///
@@ -551,7 +566,7 @@ class SourceManager : public RefCountedBase<SourceManager> {
   /// non-null, FileEntry pointers.
   llvm::DenseMap<const FileEntry*, SrcMgr::ContentCache*> FileInfos;
 
-  /// \brief True if the ContentCache for files that are overriden by other
+  /// \brief True if the ContentCache for files that are overridden by other
   /// files, should report the original file name. Defaults to true.
   bool OverridenFilesKeepOriginalName;
 
@@ -560,7 +575,7 @@ class SourceManager : public RefCountedBase<SourceManager> {
   bool UserFilesAreVolatile;
 
   struct OverriddenFilesInfoTy {
-    /// \brief Files that have been overriden with the contents from another
+    /// \brief Files that have been overridden with the contents from another
     /// file.
     llvm::DenseMap<const FileEntry *, const FileEntry *> OverriddenFiles;
     /// \brief Files that were overridden with a memory buffer.
@@ -569,7 +584,7 @@ class SourceManager : public RefCountedBase<SourceManager> {
 
   /// \brief Lazily create the object keeping overridden files info, since
   /// it is uncommonly used.
-  OwningPtr<OverriddenFilesInfoTy> OverriddenFilesInfo;
+  std::unique_ptr<OverriddenFilesInfoTy> OverriddenFilesInfo;
 
   OverriddenFilesInfoTy &getOverriddenFilesInfo() {
     if (!OverriddenFilesInfo)
@@ -704,7 +719,8 @@ public:
   FileManager &getFileManager() const { return FileMgr; }
 
   /// \brief Set true if the SourceManager should report the original file name
-  /// for contents of files that were overriden by other files.Defaults to true.
+  /// for contents of files that were overridden by other files. Defaults to
+  /// true.
   void setOverridenFilesKeepOriginalName(bool value) {
     OverridenFilesKeepOriginalName = value;
   }
@@ -729,18 +745,6 @@ public:
     StoredModuleBuildStack.push_back(std::make_pair(moduleName.str(),importLoc));
   }
 
-  /// \brief Create the FileID for a memory buffer that will represent the
-  /// FileID for the main source.
-  ///
-  /// One example of when this would be used is when the main source is read
-  /// from STDIN.
-  FileID createMainFileIDForMemBuffer(const llvm::MemoryBuffer *Buffer,
-                             SrcMgr::CharacteristicKind Kind = SrcMgr::C_User) {
-    assert(MainFileID.isInvalid() && "MainFileID already set!");
-    MainFileID = createFileIDForMemBuffer(Buffer, Kind);
-    return MainFileID;
-  }
-
   //===--------------------------------------------------------------------===//
   // MainFileID creation and querying methods.
   //===--------------------------------------------------------------------===//
@@ -748,14 +752,6 @@ public:
   /// \brief Returns the FileID of the main source file.
   FileID getMainFileID() const { return MainFileID; }
 
-  /// \brief Create the FileID for the main source file.
-  FileID createMainFileID(const FileEntry *SourceFile, 
-                          SrcMgr::CharacteristicKind Kind = SrcMgr::C_User) {
-    assert(MainFileID.isInvalid() && "MainFileID already set!");
-    MainFileID = createFileID(SourceFile, SourceLocation(), Kind);
-    return MainFileID;
-  }
-
   /// \brief Set the file ID for the main source file.
   void setMainFileID(FileID FID) {
     assert(MainFileID.isInvalid() && "MainFileID already set!");
@@ -793,10 +789,10 @@ public:
   ///
   /// This does no caching of the buffer and takes ownership of the
   /// MemoryBuffer, so only pass a MemoryBuffer to this once.
-  FileID createFileIDForMemBuffer(const llvm::MemoryBuffer *Buffer,
+  FileID createFileID(llvm::MemoryBuffer *Buffer,
                       SrcMgr::CharacteristicKind FileCharacter = SrcMgr::C_User,
-                                  int LoadedID = 0, unsigned LoadedOffset = 0,
-                                 SourceLocation IncludeLoc = SourceLocation()) {
+                      int LoadedID = 0, unsigned LoadedOffset = 0,
+                      SourceLocation IncludeLoc = SourceLocation()) {
     return createFileID(createMemBufferContentCache(Buffer), IncludeLoc,
                         FileCharacter, LoadedID, LoadedOffset);
   }
@@ -823,13 +819,13 @@ public:
   ///
   /// \param Invalid If non-NULL, will be set \c true if an error
   /// occurs while retrieving the memory buffer.
-  const llvm::MemoryBuffer *getMemoryBufferForFile(const FileEntry *File,
-                                                   bool *Invalid = 0);
+  llvm::MemoryBuffer *getMemoryBufferForFile(const FileEntry *File,
+                                             bool *Invalid = nullptr);
 
   /// \brief Override the contents of the given source file by providing an
   /// already-allocated buffer.
   ///
-  /// \param SourceFile the source file whose contents will be overriden.
+  /// \param SourceFile the source file whose contents will be overridden.
   ///
   /// \param Buffer the memory buffer whose contents will be used as the
   /// data in the given source file.
@@ -837,12 +833,11 @@ public:
   /// \param DoNotFree If true, then the buffer will not be freed when the
   /// source manager is destroyed.
   void overrideFileContents(const FileEntry *SourceFile,
-                            const llvm::MemoryBuffer *Buffer,
-                            bool DoNotFree = false);
+                            llvm::MemoryBuffer *Buffer, bool DoNotFree = false);
 
   /// \brief Override the given source file with another one.
   ///
-  /// \param SourceFile the source file which will be overriden.
+  /// \param SourceFile the source file which will be overridden.
   ///
   /// \param NewFile the file whose contents will be used as the
   /// data instead of the contents of the given source file.
@@ -875,8 +870,8 @@ public:
   ///
   /// If there is an error opening this buffer the first time, this
   /// manufactures a temporary buffer and returns a non-empty error string.
-  const llvm::MemoryBuffer *getBuffer(FileID FID, SourceLocation Loc,
-                                      bool *Invalid = 0) const {
+  llvm::MemoryBuffer *getBuffer(FileID FID, SourceLocation Loc,
+                                bool *Invalid = nullptr) const {
     bool MyInvalid = false;
     const SrcMgr::SLocEntry &Entry = getSLocEntry(FID, &MyInvalid);
     if (MyInvalid || !Entry.isFile()) {
@@ -890,7 +885,7 @@ public:
                                                         Invalid);
   }
 
-  const llvm::MemoryBuffer *getBuffer(FileID FID, bool *Invalid = 0) const {
+  llvm::MemoryBuffer *getBuffer(FileID FID, bool *Invalid = nullptr) const {
     bool MyInvalid = false;
     const SrcMgr::SLocEntry &Entry = getSLocEntry(FID, &MyInvalid);
     if (MyInvalid || !Entry.isFile()) {
@@ -910,11 +905,11 @@ public:
     bool MyInvalid = false;
     const SrcMgr::SLocEntry &Entry = getSLocEntry(FID, &MyInvalid);
     if (MyInvalid || !Entry.isFile())
-      return 0;
+      return nullptr;
 
     const SrcMgr::ContentCache *Content = Entry.getFile().getContentCache();
     if (!Content)
-      return 0;
+      return nullptr;
     return Content->OrigEntry;
   }
 
@@ -923,7 +918,7 @@ public:
   {
     const SrcMgr::ContentCache *Content = sloc.getFile().getContentCache();
     if (!Content)
-      return 0;
+      return nullptr;
     return Content->OrigEntry;
   }
 
@@ -932,7 +927,7 @@ public:
   ///
   /// \param FID The file ID whose contents will be returned.
   /// \param Invalid If non-NULL, will be set true if an error occurred.
-  StringRef getBufferData(FileID FID, bool *Invalid = 0) const;
+  StringRef getBufferData(FileID FID, bool *Invalid = nullptr) const;
 
   /// \brief Get the number of FileIDs (files and macros) that were created
   /// during preprocessing of \p FID, including it.
@@ -1167,15 +1162,16 @@ public:
   /// \param MacroBegin If non-null and function returns true, it is set to the
   /// begin location of the immediate macro expansion.
   bool isAtStartOfImmediateMacroExpansion(SourceLocation Loc,
-                                          SourceLocation *MacroBegin = 0) const;
+                                    SourceLocation *MacroBegin = nullptr) const;
 
   /// \brief Returns true if the given MacroID location points at the character
   /// end of the immediate macro expansion.
   ///
   /// \param MacroEnd If non-null and function returns true, it is set to the
   /// character end location of the immediate macro expansion.
-  bool isAtEndOfImmediateMacroExpansion(SourceLocation Loc,
-                                        SourceLocation *MacroEnd = 0) const;
+  bool
+  isAtEndOfImmediateMacroExpansion(SourceLocation Loc,
+                                   SourceLocation *MacroEnd = nullptr) const;
 
   /// \brief Returns true if \p Loc is inside the [\p Start, +\p Length)
   /// chunk of the source location address space.
@@ -1184,7 +1180,7 @@ public:
   /// relative offset of \p Loc inside the chunk.
   bool isInSLocAddrSpace(SourceLocation Loc,
                          SourceLocation Start, unsigned Length,
-                         unsigned *RelativeOffset = 0) const {
+                         unsigned *RelativeOffset = nullptr) const {
     assert(((Start.getOffset() < NextLocalOffset &&
                Start.getOffset()+Length <= NextLocalOffset) ||
             (Start.getOffset() >= CurrentLoadedOffset &&
@@ -1230,7 +1226,8 @@ public:
   /// in the appropriate spelling MemoryBuffer.
   ///
   /// \param Invalid If non-NULL, will be set \c true if an error occurs.
-  const char *getCharacterData(SourceLocation SL, bool *Invalid = 0) const;
+  const char *getCharacterData(SourceLocation SL,
+                               bool *Invalid = nullptr) const;
 
   /// \brief Return the column # for the specified file position.
   ///
@@ -1239,12 +1236,13 @@ public:
   /// on a file sloc, so you must choose a spelling or expansion location
   /// before calling this method.
   unsigned getColumnNumber(FileID FID, unsigned FilePos,
-                           bool *Invalid = 0) const;
-  unsigned getSpellingColumnNumber(SourceLocation Loc, bool *Invalid = 0) const;
+                           bool *Invalid = nullptr) const;
+  unsigned getSpellingColumnNumber(SourceLocation Loc,
+                                   bool *Invalid = nullptr) const;
   unsigned getExpansionColumnNumber(SourceLocation Loc,
-                                    bool *Invalid = 0) const;
-  unsigned getPresumedColumnNumber(SourceLocation Loc, bool *Invalid = 0) const;
-
+                                    bool *Invalid = nullptr) const;
+  unsigned getPresumedColumnNumber(SourceLocation Loc,
+                                   bool *Invalid = nullptr) const;
 
   /// \brief Given a SourceLocation, return the spelling line number
   /// for the position indicated.
@@ -1252,17 +1250,17 @@ public:
   /// This requires building and caching a table of line offsets for the
   /// MemoryBuffer, so this is not cheap: use only when about to emit a
   /// diagnostic.
-  unsigned getLineNumber(FileID FID, unsigned FilePos, bool *Invalid = 0) const;
-  unsigned getSpellingLineNumber(SourceLocation Loc, bool *Invalid = 0) const;
-  unsigned getExpansionLineNumber(SourceLocation Loc, bool *Invalid = 0) const;
-  unsigned getPresumedLineNumber(SourceLocation Loc, bool *Invalid = 0) const;
+  unsigned getLineNumber(FileID FID, unsigned FilePos, bool *Invalid = nullptr) const;
+  unsigned getSpellingLineNumber(SourceLocation Loc, bool *Invalid = nullptr) const;
+  unsigned getExpansionLineNumber(SourceLocation Loc, bool *Invalid = nullptr) const;
+  unsigned getPresumedLineNumber(SourceLocation Loc, bool *Invalid = nullptr) const;
 
   /// \brief Return the filename or buffer identifier of the buffer the
   /// location is in.
   ///
   /// Note that this name does not respect \#line directives.  Use
   /// getPresumedLoc for normal clients.
-  const char *getBufferName(SourceLocation Loc, bool *Invalid = 0) const;
+  const char *getBufferName(SourceLocation Loc, bool *Invalid = nullptr) const;
 
   /// \brief Return the file characteristic of the specified source
   /// location, indicating whether this is a normal file, a system
@@ -1286,7 +1284,7 @@ public:
   /// an expansion location, not at the spelling location.
   ///
   /// \returns The presumed location of the specified SourceLocation. If the
-  /// presumed location cannot be calculate (e.g., because \p Loc is invalid
+  /// presumed location cannot be calculated (e.g., because \p Loc is invalid
   /// or the file containing \p Loc has changed on disk), returns an invalid
   /// presumed location.
   PresumedLoc getPresumedLoc(SourceLocation Loc,
@@ -1299,9 +1297,7 @@ public:
   /// whether it came from a file other than the main file. This is different
   /// from isWrittenInMainFile() because it takes line marker directives into
   /// account.
-  bool isInMainFile(SourceLocation Loc) const {
-    return getPresumedLoc(Loc).getIncludeLoc().isInvalid();
-  }
+  bool isInMainFile(SourceLocation Loc) const;
 
   /// \brief Returns true if the spelling locations for both SourceLocations
   /// are part of the same file buffer.
@@ -1334,14 +1330,14 @@ public:
     return loc.isMacroID() && isInSystemHeader(getSpellingLoc(loc));
   }
 
-  /// \brief The size of the SLocEnty that \p FID represents.
+  /// \brief The size of the SLocEntry that \p FID represents.
   unsigned getFileIDSize(FileID FID) const;
 
   /// \brief Given a specific FileID, returns true if \p Loc is inside that
   /// FileID chunk and sets relative offset (offset of \p Loc from beginning
   /// of FileID) to \p relativeOffset.
   bool isInFileID(SourceLocation Loc, FileID FID,
-                  unsigned *RelativeOffset = 0) const {
+                  unsigned *RelativeOffset = nullptr) const {
     unsigned Offs = Loc.getOffset();
     if (isOffsetInFileID(FID, Offs)) {
       if (RelativeOffset)
@@ -1370,7 +1366,7 @@ public:
                    bool IsSystemHeader, bool IsExternCHeader);
 
   /// \brief Determine if the source manager has a line table.
-  bool hasLineTable() const { return LineTable != 0; }
+  bool hasLineTable() const { return LineTable != nullptr; }
 
   /// \brief Retrieve the stored line table.
   LineTableInfo &getLineTable();
@@ -1477,7 +1473,7 @@ public:
 
   /// \brief Get a local SLocEntry. This is exposed for indexing.
   const SrcMgr::SLocEntry &getLocalSLocEntry(unsigned Index,
-                                             bool *Invalid = 0) const {
+                                             bool *Invalid = nullptr) const {
     assert(Index < LocalSLocEntryTable.size() && "Invalid index");
     return LocalSLocEntryTable[Index];
   }
@@ -1487,14 +1483,15 @@ public:
 
   /// \brief Get a loaded SLocEntry. This is exposed for indexing.
   const SrcMgr::SLocEntry &getLoadedSLocEntry(unsigned Index,
-                                              bool *Invalid = 0) const {
+                                              bool *Invalid = nullptr) const {
     assert(Index < LoadedSLocEntryTable.size() && "Invalid index");
     if (SLocEntryLoaded[Index])
       return LoadedSLocEntryTable[Index];
     return loadSLocEntry(Index, Invalid);
   }
 
-  const SrcMgr::SLocEntry &getSLocEntry(FileID FID, bool *Invalid = 0) const {
+  const SrcMgr::SLocEntry &getSLocEntry(FileID FID,
+                                        bool *Invalid = nullptr) const {
     if (FID.ID == 0 || FID.ID == -1) {
       if (Invalid) *Invalid = true;
       return LocalSLocEntryTable[0];
@@ -1557,21 +1554,22 @@ public:
   }
 
 private:
-  const llvm::MemoryBuffer *getFakeBufferForRecovery() const;
+  llvm::MemoryBuffer *getFakeBufferForRecovery() const;
   const SrcMgr::ContentCache *getFakeContentCacheForRecovery() const;
 
   const SrcMgr::SLocEntry &loadSLocEntry(unsigned Index, bool *Invalid) const;
 
   /// \brief Get the entry with the given unwrapped FileID.
-  const SrcMgr::SLocEntry &getSLocEntryByID(int ID, bool *Invalid = 0) const {
+  const SrcMgr::SLocEntry &getSLocEntryByID(int ID,
+                                            bool *Invalid = nullptr) const {
     assert(ID != -1 && "Using FileID sentinel value");
     if (ID < 0)
       return getLoadedSLocEntryByID(ID, Invalid);
     return getLocalSLocEntry(static_cast<unsigned>(ID), Invalid);
   }
 
-  const SrcMgr::SLocEntry &getLoadedSLocEntryByID(int ID,
-                                                  bool *Invalid = 0) const {
+  const SrcMgr::SLocEntry &
+  getLoadedSLocEntryByID(int ID, bool *Invalid = nullptr) const {
     return getLoadedSLocEntry(static_cast<unsigned>(-ID - 2), Invalid);
   }
 
@@ -1625,8 +1623,8 @@ private:
                             bool isSystemFile = false);
 
   /// \brief Create a new ContentCache for the specified  memory buffer.
-  const SrcMgr::ContentCache*
-  createMemBufferContentCache(const llvm::MemoryBuffer *Buf);
+  const SrcMgr::ContentCache *
+  createMemBufferContentCache(llvm::MemoryBuffer *Buf);
 
   FileID getFileIDSlow(unsigned SLocOffset) const;
   FileID getFileIDLocal(unsigned SLocOffset) const;