aboutsummaryrefslogtreecommitdiff
path: root/clang/lib/Basic/SourceManager.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'clang/lib/Basic/SourceManager.cpp')
-rw-r--r--clang/lib/Basic/SourceManager.cpp87
1 files changed, 85 insertions, 2 deletions
diff --git a/clang/lib/Basic/SourceManager.cpp b/clang/lib/Basic/SourceManager.cpp
index 187c33a..8ba5815 100644
--- a/clang/lib/Basic/SourceManager.cpp
+++ b/clang/lib/Basic/SourceManager.cpp
@@ -17,12 +17,12 @@
#include "clang/Basic/SourceLocation.h"
#include "clang/Basic/SourceManagerInternals.h"
#include "llvm/ADT/DenseMap.h"
-#include "llvm/ADT/Optional.h"
#include "llvm/ADT/None.h"
+#include "llvm/ADT/Optional.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/SmallVector.h"
-#include "llvm/ADT/StringSwitch.h"
#include "llvm/ADT/StringRef.h"
+#include "llvm/ADT/StringSwitch.h"
#include "llvm/Support/Allocator.h"
#include "llvm/Support/Capacity.h"
#include "llvm/Support/Compiler.h"
@@ -560,6 +560,70 @@ FileID SourceManager::getNextFileID(FileID FID) const {
// Methods to create new FileID's and macro expansions.
//===----------------------------------------------------------------------===//
+/// Create a new FileID that represents the specified file
+/// being \#included from the specified IncludePosition.
+///
+/// This translates NULL into standard input.
+FileID SourceManager::createFileID(const FileEntry *SourceFile,
+ SourceLocation IncludePos,
+ SrcMgr::CharacteristicKind FileCharacter,
+ int LoadedID, unsigned LoadedOffset) {
+ assert(SourceFile && "Null source file!");
+ const SrcMgr::ContentCache *IR =
+ getOrCreateContentCache(SourceFile, isSystem(FileCharacter));
+ assert(IR && "getOrCreateContentCache() cannot return NULL");
+ return createFileID(IR, SourceFile->getName(), IncludePos, FileCharacter,
+ LoadedID, LoadedOffset);
+}
+
+FileID SourceManager::createFileID(FileEntryRef SourceFile,
+ SourceLocation IncludePos,
+ SrcMgr::CharacteristicKind FileCharacter,
+ int LoadedID, unsigned LoadedOffset) {
+ 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.
+///
+/// This does no caching of the buffer and takes ownership of the
+/// MemoryBuffer, so only pass a MemoryBuffer to this once.
+FileID SourceManager::createFileID(std::unique_ptr<llvm::MemoryBuffer> Buffer,
+ SrcMgr::CharacteristicKind FileCharacter,
+ int LoadedID, unsigned LoadedOffset,
+ SourceLocation IncludeLoc) {
+ StringRef Name = Buffer->getBufferIdentifier();
+ return createFileID(
+ createMemBufferContentCache(Buffer.release(), /*DoNotFree*/ false),
+ Name, IncludeLoc, FileCharacter, LoadedID, LoadedOffset);
+}
+
+/// Create a new FileID that represents the specified memory buffer.
+///
+/// This does not take ownership of the MemoryBuffer. The memory buffer must
+/// outlive the SourceManager.
+FileID SourceManager::createFileID(UnownedTag, const llvm::MemoryBuffer *Buffer,
+ SrcMgr::CharacteristicKind FileCharacter,
+ int LoadedID, unsigned LoadedOffset,
+ SourceLocation IncludeLoc) {
+ return createFileID(createMemBufferContentCache(Buffer, /*DoNotFree*/ true),
+ Buffer->getBufferIdentifier(), IncludeLoc,
+ FileCharacter, LoadedID, LoadedOffset);
+}
+
+/// Get the FileID for \p SourceFile if it exists. Otherwise, create a
+/// new FileID for the \p SourceFile.
+FileID
+SourceManager::getOrCreateFileID(const FileEntry *SourceFile,
+ SrcMgr::CharacteristicKind FileCharacter) {
+ FileID ID = translateFile(SourceFile);
+ return ID.isValid() ? ID : createFileID(SourceFile, SourceLocation(),
+ FileCharacter);
+}
+
/// createFileID - Create a new FileID for the specified ContentCache and
/// include position. This works regardless of whether the ContentCache
/// corresponds to a file or some other input source.
@@ -701,6 +765,18 @@ void SourceManager::setFileIsTransient(const FileEntry *File) {
const_cast<SrcMgr::ContentCache *>(CC)->IsTransient = true;
}
+Optional<FileEntryRef> SourceManager::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);
+}
+
StringRef SourceManager::getBufferData(FileID FID, bool *Invalid) const {
bool MyInvalid = false;
const SLocEntry &SLoc = getSLocEntry(FID, &MyInvalid);
@@ -992,6 +1068,13 @@ SourceLocation SourceManager::getImmediateSpellingLoc(SourceLocation Loc) const{
return Loc.getLocWithOffset(LocInfo.second);
}
+/// Return the filename of the file containing a SourceLocation.
+StringRef SourceManager::getFilename(SourceLocation SpellingLoc) const {
+ if (const FileEntry *F = getFileEntryForID(getFileID(SpellingLoc)))
+ return F->getName();
+ return StringRef();
+}
+
/// getImmediateExpansionRange - Loc is required to be an expansion location.
/// Return the start/end of the expansion information.
CharSourceRange