diff options
Diffstat (limited to 'include/clang/Basic/SourceManager.h')
-rw-r--r-- | include/clang/Basic/SourceManager.h | 83 |
1 files changed, 59 insertions, 24 deletions
diff --git a/include/clang/Basic/SourceManager.h b/include/clang/Basic/SourceManager.h index e32f749ae6abd..3185ca0f4a25c 100644 --- a/include/clang/Basic/SourceManager.h +++ b/include/clang/Basic/SourceManager.h @@ -140,9 +140,9 @@ namespace SrcMgr { /// exist. unsigned BufferOverridden : 1; - /// True if this content cache was initially created for a source - /// file considered as a system one. - unsigned IsSystemFile : 1; + /// True if this content cache was initially created for a source file + /// considered to be volatile (likely to change between stat and open). + unsigned IsFileVolatile : 1; /// True if this file may be transient, that is, if it might not /// exist at some later point in time when this content entry is used, @@ -152,15 +152,15 @@ namespace SrcMgr { ContentCache(const FileEntry *Ent = nullptr) : ContentCache(Ent, Ent) {} ContentCache(const FileEntry *Ent, const FileEntry *contentEnt) - : Buffer(nullptr, false), OrigEntry(Ent), ContentsEntry(contentEnt), - BufferOverridden(false), IsSystemFile(false), IsTransient(false) {} + : Buffer(nullptr, false), OrigEntry(Ent), ContentsEntry(contentEnt), + BufferOverridden(false), IsFileVolatile(false), IsTransient(false) {} /// The copy ctor does not allow copies where source object has either /// a non-NULL Buffer or SourceLineCache. Ownership of allocated memory /// is not transferred, so this is a logical error. ContentCache(const ContentCache &RHS) - : Buffer(nullptr, false), BufferOverridden(false), IsSystemFile(false), - IsTransient(false) { + : Buffer(nullptr, false), BufferOverridden(false), + IsFileVolatile(false), IsTransient(false) { OrigEntry = RHS.OrigEntry; ContentsEntry = RHS.ContentsEntry; @@ -185,7 +185,7 @@ namespace SrcMgr { /// /// \param Invalid If non-NULL, will be set \c true if an error occurred. const llvm::MemoryBuffer *getBuffer(DiagnosticsEngine &Diag, - const SourceManager &SM, + FileManager &FM, SourceLocation Loc = SourceLocation(), bool *Invalid = nullptr) const; @@ -265,16 +265,21 @@ namespace SrcMgr { llvm::PointerIntPair<const ContentCache*, 3, CharacteristicKind> ContentAndKind; + /// The filename that is used to access the file entry represented by the + /// content cache. + StringRef Filename; + public: /// Return a FileInfo object. static FileInfo get(SourceLocation IL, const ContentCache *Con, - CharacteristicKind FileCharacter) { + CharacteristicKind FileCharacter, StringRef Filename) { FileInfo X; X.IncludeLoc = IL.getRawEncoding(); X.NumCreatedFIDs = 0; X.HasLineDirectives = false; X.ContentAndKind.setPointer(Con); X.ContentAndKind.setInt(FileCharacter); + X.Filename = Filename; return X; } @@ -299,6 +304,10 @@ namespace SrcMgr { void setHasLineDirectives() { HasLineDirectives = true; } + + /// Returns the name of the file that was used when the file was loaded from + /// the underlying file system. + StringRef getName() const { return Filename; } }; /// Each ExpansionInfo encodes the expansion location - where @@ -821,7 +830,18 @@ public: const SrcMgr::ContentCache *IR = getOrCreateContentCache(SourceFile, isSystem(FileCharacter)); assert(IR && "getOrCreateContentCache() cannot return NULL"); - return createFileID(IR, IncludePos, FileCharacter, LoadedID, LoadedOffset); + return createFileID(IR, SourceFile->getName(), IncludePos, FileCharacter, + LoadedID, LoadedOffset); + } + + FileID createFileID(FileEntryRef SourceFile, SourceLocation IncludePos, + SrcMgr::CharacteristicKind FileCharacter, + int LoadedID = 0, unsigned LoadedOffset = 0) { + const SrcMgr::ContentCache *IR = getOrCreateContentCache( + &SourceFile.getFileEntry(), isSystem(FileCharacter)); + assert(IR && "getOrCreateContentCache() cannot return NULL"); + return createFileID(IR, SourceFile.getName(), IncludePos, FileCharacter, + LoadedID, LoadedOffset); } /// Create a new FileID that represents the specified memory buffer. @@ -832,9 +852,10 @@ public: SrcMgr::CharacteristicKind FileCharacter = SrcMgr::C_User, int LoadedID = 0, unsigned LoadedOffset = 0, SourceLocation IncludeLoc = SourceLocation()) { + StringRef Name = Buffer->getBufferIdentifier(); return createFileID( createMemBufferContentCache(Buffer.release(), /*DoNotFree*/ false), - IncludeLoc, FileCharacter, LoadedID, LoadedOffset); + Name, IncludeLoc, FileCharacter, LoadedID, LoadedOffset); } enum UnownedTag { Unowned }; @@ -847,8 +868,9 @@ public: SrcMgr::CharacteristicKind FileCharacter = SrcMgr::C_User, int LoadedID = 0, unsigned LoadedOffset = 0, SourceLocation IncludeLoc = SourceLocation()) { - return createFileID(createMemBufferContentCache(Buffer, /*DoNotFree*/true), - IncludeLoc, FileCharacter, LoadedID, LoadedOffset); + return createFileID(createMemBufferContentCache(Buffer, /*DoNotFree*/ true), + Buffer->getBufferIdentifier(), IncludeLoc, + FileCharacter, LoadedID, LoadedOffset); } /// Get the FileID for \p SourceFile if it exists. Otherwise, create a @@ -930,11 +952,12 @@ public: return false; } - /// Disable overridding the contents of a file, previously enabled - /// with #overrideFileContents. + /// Bypass the overridden contents of a file. This creates a new FileEntry + /// and initializes the content cache for it. Returns nullptr if there is no + /// such file in the filesystem. /// /// This should be called before parsing has begun. - void disableFileContentsOverride(const FileEntry *File); + const FileEntry *bypassFileContentsOverride(const FileEntry &File); /// Specify that a file is transient. void setFileIsTransient(const FileEntry *SourceFile); @@ -964,8 +987,8 @@ public: return getFakeBufferForRecovery(); } - return Entry.getFile().getContentCache()->getBuffer(Diag, *this, Loc, - Invalid); + return Entry.getFile().getContentCache()->getBuffer(Diag, getFileManager(), + Loc, Invalid); } const llvm::MemoryBuffer *getBuffer(FileID FID, @@ -979,9 +1002,8 @@ public: return getFakeBufferForRecovery(); } - return Entry.getFile().getContentCache()->getBuffer(Diag, *this, - SourceLocation(), - Invalid); + return Entry.getFile().getContentCache()->getBuffer( + Diag, getFileManager(), SourceLocation(), Invalid); } /// Returns the FileEntry record for the provided FileID. @@ -997,6 +1019,19 @@ public: return Content->OrigEntry; } + /// Returns the FileEntryRef for the provided FileID. + Optional<FileEntryRef> getFileEntryRefForID(FileID FID) const { + bool Invalid = false; + const SrcMgr::SLocEntry &Entry = getSLocEntry(FID, &Invalid); + if (Invalid || !Entry.isFile()) + return None; + + const SrcMgr::ContentCache *Content = Entry.getFile().getContentCache(); + if (!Content || !Content->OrigEntry) + return None; + return FileEntryRef(Entry.getFile().getName(), *Content->OrigEntry); + } + /// Returns the FileEntry record for the provided SLocEntry. const FileEntry *getFileEntryForSLocEntry(const SrcMgr::SLocEntry &sloc) const { @@ -1785,10 +1820,10 @@ private: /// /// This works regardless of whether the ContentCache corresponds to a /// file or some other input source. - FileID createFileID(const SrcMgr::ContentCache* File, + FileID createFileID(const SrcMgr::ContentCache *File, StringRef Filename, SourceLocation IncludePos, - SrcMgr::CharacteristicKind DirCharacter, - int LoadedID, unsigned LoadedOffset); + SrcMgr::CharacteristicKind DirCharacter, int LoadedID, + unsigned LoadedOffset); const SrcMgr::ContentCache * getOrCreateContentCache(const FileEntry *SourceFile, |