summaryrefslogtreecommitdiff
path: root/source/slang/source-loc.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'source/slang/source-loc.cpp')
-rw-r--r--source/slang/source-loc.cpp591
1 files changed, 0 insertions, 591 deletions
diff --git a/source/slang/source-loc.cpp b/source/slang/source-loc.cpp
deleted file mode 100644
index c66fdedb5..000000000
--- a/source/slang/source-loc.cpp
+++ /dev/null
@@ -1,591 +0,0 @@
-// source-loc.cpp
-#include "source-loc.h"
-
-#include "compiler.h"
-
-#include "../core/slang-string-util.h"
-
-namespace Slang {
-
-/* !!!!!!!!!!!!!!!!!!!!!!!!! SourceView !!!!!!!!!!!!!!!!!!!!!!!!!!!! */
-
-const String PathInfo::getMostUniqueIdentity() const
-{
- switch (type)
- {
- case Type::Normal: return uniqueIdentity;
- case Type::FoundPath:
- case Type::FromString:
- {
- return foundPath;
- }
- default: return "";
- }
-}
-
-/* !!!!!!!!!!!!!!!!!!!!!!!!! SourceView !!!!!!!!!!!!!!!!!!!!!!!!!!!! */
-
-int SourceView::findEntryIndex(SourceLoc sourceLoc) const
-{
- if (!m_range.contains(sourceLoc))
- {
- return -1;
- }
-
- const auto rawValue = sourceLoc.getRaw();
-
- Index hi = m_entries.getCount();
- // If there are no entries, or it is in front of the first entry, then there is no associated entry
- if (hi == 0 ||
- m_entries[0].m_startLoc.getRaw() > sourceLoc.getRaw())
- {
- return -1;
- }
-
- Index lo = 0;
- while (lo + 1 < hi)
- {
- const Index mid = (hi + lo) >> 1;
- const Entry& midEntry = m_entries[mid];
- SourceLoc::RawValue midValue = midEntry.m_startLoc.getRaw();
- if (midValue <= rawValue)
- {
- // The location we seek is at or after this entry
- lo = mid;
- }
- else
- {
- // The location we seek is before this entry
- hi = mid;
- }
- }
-
- return int(lo);
-}
-
-void SourceView::addLineDirective(SourceLoc directiveLoc, StringSlicePool::Handle pathHandle, int line)
-{
- SLANG_ASSERT(pathHandle != StringSlicePool::Handle(0));
- SLANG_ASSERT(m_range.contains(directiveLoc));
-
- // Check that the directiveLoc values are always increasing
- SLANG_ASSERT(m_entries.getCount() == 0 || (m_entries.getLast().m_startLoc.getRaw() < directiveLoc.getRaw()));
-
- // Calculate the offset
- const int offset = m_range.getOffset(directiveLoc);
-
- // Get the line index in the original file
- const int lineIndex = m_sourceFile->calcLineIndexFromOffset(offset);
-
- Entry entry;
- entry.m_startLoc = directiveLoc;
- entry.m_pathHandle = pathHandle;
-
- // We also need to make sure that any lookups for line numbers will
- // get corrected based on this files location.
- // We assume the line number coming from the directive is a line number, NOT an index, so the correction needs + 1
- // There is an additional + 1 because we want the NEXT line - ie the line after the #line directive, to the specified value
- // Taking both into account means +2 is correct 'fix'
- entry.m_lineAdjust = line - (lineIndex + 2);
-
- m_entries.add(entry);
-}
-
-void SourceView::addLineDirective(SourceLoc directiveLoc, const String& path, int line)
-{
- StringSlicePool::Handle pathHandle = getSourceManager()->getStringSlicePool().add(path.getUnownedSlice());
- return addLineDirective(directiveLoc, pathHandle, line);
-}
-
-void SourceView::addDefaultLineDirective(SourceLoc directiveLoc)
-{
- SLANG_ASSERT(m_range.contains(directiveLoc));
- // Check that the directiveLoc values are always increasing
- SLANG_ASSERT(m_entries.getCount() == 0 || (m_entries.getLast().m_startLoc.getRaw() < directiveLoc.getRaw()));
-
- // Well if there are no entries, or the last one puts it in default case, then we don't need to add anything
- if (m_entries.getCount() == 0 || (m_entries.getCount() && m_entries.getLast().isDefault()))
- {
- return;
- }
-
- Entry entry;
- entry.m_startLoc = directiveLoc;
- entry.m_lineAdjust = 0; // No line adjustment... we are going back to default
- entry.m_pathHandle = StringSlicePool::Handle(0); // Mark that there is no path, and that this is a 'default'
-
- SLANG_ASSERT(entry.isDefault());
-
- m_entries.add(entry);
-}
-
-HumaneSourceLoc SourceView::getHumaneLoc(SourceLoc loc, SourceLocType type)
-{
- const int offset = m_range.getOffset(loc);
-
- // We need the line index from the original source file
- const int lineIndex = m_sourceFile->calcLineIndexFromOffset(offset);
-
- // TODO: we should really translate the byte index in the line
- // to deal with:
- //
- // - Non-ASCII characters, while might consume multiple bytes
- //
- // - Tab characters, which should really adjust how we report
- // columns (although how are we supposed to know the setting
- // that an IDE expects us to use when reporting locations?)
- const int columnIndex = m_sourceFile->calcColumnIndex(lineIndex, offset);
-
- HumaneSourceLoc humaneLoc;
- humaneLoc.column = columnIndex + 1;
- humaneLoc.line = lineIndex + 1;
-
- // Make up a default entry
- StringSlicePool::Handle pathHandle = StringSlicePool::Handle(0);
-
- // Only bother looking up the entry information if we want a 'Normal' lookup
- const int entryIndex = (type == SourceLocType::Nominal) ? findEntryIndex(loc) : -1;
- if (entryIndex >= 0)
- {
- const Entry& entry = m_entries[entryIndex];
- // Adjust the line
- humaneLoc.line += entry.m_lineAdjust;
- // Get the pathHandle..
- pathHandle = entry.m_pathHandle;
- }
-
- humaneLoc.pathInfo = _getPathInfoFromHandle(pathHandle);
- return humaneLoc;
-}
-
-PathInfo SourceView::_getPathInfo() const
-{
- if (m_viewPath.getLength())
- {
- PathInfo pathInfo(m_sourceFile->getPathInfo());
- pathInfo.foundPath = m_viewPath;
- return pathInfo;
- }
- else
- {
- return m_sourceFile->getPathInfo();
- }
-}
-
-PathInfo SourceView::_getPathInfoFromHandle(StringSlicePool::Handle pathHandle) const
-{
- // If there is no override path, then just the source files path
- if (pathHandle == StringSlicePool::Handle(0))
- {
- return _getPathInfo();
- }
- else
- {
- return PathInfo::makePath(getSourceManager()->getStringSlicePool().getSlice(pathHandle));
- }
-}
-
-PathInfo SourceView::getPathInfo(SourceLoc loc, SourceLocType type)
-{
- if (type == SourceLocType::Actual)
- {
- return _getPathInfo();
- }
-
- const int entryIndex = findEntryIndex(loc);
- return _getPathInfoFromHandle((entryIndex >= 0) ? m_entries[entryIndex].m_pathHandle : StringSlicePool::Handle(0));
-}
-
-/* !!!!!!!!!!!!!!!!!!!!!!! SourceFile !!!!!!!!!!!!!!!!!!!!!!!!!!!! */
-
-void SourceFile::setLineBreakOffsets(const uint32_t* offsets, UInt numOffsets)
-{
- m_lineBreakOffsets.clear();
- m_lineBreakOffsets.addRange(offsets, numOffsets);
-}
-
-const List<uint32_t>& SourceFile::getLineBreakOffsets()
-{
- // We now have a raw input file that we can search for line breaks.
- // We obviously don't want to do a linear scan over and over, so we will
- // cache an array of line break locations in the file.
- if (m_lineBreakOffsets.getCount() == 0)
- {
- UnownedStringSlice content = getContent();
-
- char const* begin = content.begin();
- char const* end = content.end();
-
- char const* cursor = begin;
-
- // Treat the beginning of the file as a line break
- m_lineBreakOffsets.add(0);
-
- while (cursor != end)
- {
- int c = *cursor++;
- switch (c)
- {
- case '\r': case '\n':
- {
- // When we see a line-break character we need
- // to record the line break, but we also need
- // to deal with the annoying issue of encodings,
- // where a multi-byte sequence might encode
- // the line break.
-
- // Check to make sure that the EOF hasn't been reached.
- if (cursor != end)
- {
- int d = *cursor;
- if ((c ^ d) == ('\r' ^ '\n'))
- cursor++;
- }
-
- m_lineBreakOffsets.add(uint32_t(cursor - begin));
- break;
- }
- default:
- break;
- }
- }
-
- // Note that we do *not* treat the end of the file as a line
- // break, because otherwise we would report errors like
- // "end of file inside string literal" with a line number
- // that points at a line that doesn't exist.
- }
-
- return m_lineBreakOffsets;
-}
-
-int SourceFile::calcLineIndexFromOffset(int offset)
-{
- SLANG_ASSERT(UInt(offset) <= getContentSize());
-
- // Make sure we have the line break offsets
- const auto& lineBreakOffsets = getLineBreakOffsets();
-
- // At this point we can assume the `lineBreakOffsets` array has been filled in.
- // We will use a binary search to find the line index that contains our
- // chosen offset.
- Index lo = 0;
- Index hi = lineBreakOffsets.getCount();
-
- while (lo + 1 < hi)
- {
- const Index mid = (hi + lo) >> 1;
- const uint32_t midOffset = lineBreakOffsets[mid];
- if (midOffset <= uint32_t(offset))
- {
- lo = mid;
- }
- else
- {
- hi = mid;
- }
- }
-
- return int(lo);
-}
-
-int SourceFile::calcColumnIndex(int lineIndex, int offset)
-{
- const auto& lineBreakOffsets = getLineBreakOffsets();
- return offset - lineBreakOffsets[lineIndex];
-}
-
-/* !!!!!!!!!!!!!!!!!!!!!!!!! SourceFile !!!!!!!!!!!!!!!!!!!!!!!!!!!! */
-
-void SourceFile::setContents(ISlangBlob* blob)
-{
- const UInt contentSize = blob->getBufferSize();
-
- SLANG_ASSERT(contentSize == m_contentSize);
-
- char const* contentBegin = (char const*)blob->getBufferPointer();
- char const* contentEnd = contentBegin + contentSize;
-
- m_contentBlob = blob;
- m_content = UnownedStringSlice(contentBegin, contentEnd);
-}
-
-void SourceFile::setContents(const String& content)
-{
- ComPtr<ISlangBlob> contentBlob = StringUtil::createStringBlob(content);
- setContents(contentBlob);
-}
-
-SourceFile::SourceFile(SourceManager* sourceManager, const PathInfo& pathInfo, size_t contentSize) :
- m_sourceManager(sourceManager),
- m_pathInfo(pathInfo),
- m_contentSize(contentSize)
-{
-}
-
-SourceFile::~SourceFile()
-{
-}
-
-String SourceFile::calcVerbosePath() const
-{
- ISlangFileSystemExt* fileSystemExt = getSourceManager()->getFileSystemExt();
-
- if (fileSystemExt)
- {
- String canonicalPath;
- ComPtr<ISlangBlob> canonicalPathBlob;
- if (SLANG_SUCCEEDED(fileSystemExt->getCanonicalPath(m_pathInfo.foundPath.getBuffer(), canonicalPathBlob.writeRef())))
- {
- canonicalPath = StringUtil::getString(canonicalPathBlob);
- }
- if (canonicalPath.getLength() > 0)
- {
- return canonicalPath;
- }
- }
-
- return m_pathInfo.foundPath;
-}
-
-/* !!!!!!!!!!!!!!!!!!!!!!!!! SourceManager !!!!!!!!!!!!!!!!!!!!!!!!!!!! */
-
-void SourceManager::initialize(
- SourceManager* p,
- ISlangFileSystemExt* fileSystemExt)
-{
- m_fileSystemExt = fileSystemExt;
-
- m_parent = p;
-
- if( p )
- {
- // If we have a parent source manager, then we assume that all code at that level
- // has already been loaded, and it is safe to start our own source locations
- // right after those from the parent.
- //
- // TODO: more clever allocation in cases where that might not be reasonable
- m_startLoc = p->m_nextLoc;
- }
- else
- {
- // Location zero is reserved for an invalid location,
- // so we need to start reserving locations starting at 1.
- m_startLoc = SourceLoc::fromRaw(1);
- }
-
- m_nextLoc = m_startLoc;
-}
-
-SourceManager::~SourceManager()
-{
- for (auto item : m_sourceViews)
- {
- delete item;
- }
-
- for (auto item : m_sourceFiles)
- {
- delete item;
- }
-}
-
-UnownedStringSlice SourceManager::allocateStringSlice(const UnownedStringSlice& slice)
-{
- const UInt numChars = slice.size();
-
- char* dst = (char*)m_memoryArena.allocate(numChars);
- ::memcpy(dst, slice.begin(), numChars);
-
- return UnownedStringSlice(dst, numChars);
-}
-
-SourceRange SourceManager::allocateSourceRange(UInt size)
-{
- // TODO: consider using atomics here
-
-
- SourceLoc beginLoc = m_nextLoc;
- SourceLoc endLoc = beginLoc + size;
-
- // We need to be able to represent the location that is *at* the end of
- // the input source, so the next available location for a new file
- // must be placed one after the end of this one.
-
- m_nextLoc = endLoc + 1;
-
- return SourceRange(beginLoc, endLoc);
-}
-
-SourceFile* SourceManager::createSourceFileWithSize(const PathInfo& pathInfo, size_t contentSize)
-{
- SourceFile* sourceFile = new SourceFile(this, pathInfo, contentSize);
- m_sourceFiles.add(sourceFile);
- return sourceFile;
-}
-
-SourceFile* SourceManager::createSourceFileWithString(const PathInfo& pathInfo, const String& contents)
-{
- SourceFile* sourceFile = new SourceFile(this, pathInfo, contents.getLength());
- m_sourceFiles.add(sourceFile);
- sourceFile->setContents(contents);
- return sourceFile;
-}
-
-SourceFile* SourceManager::createSourceFileWithBlob(const PathInfo& pathInfo, ISlangBlob* blob)
-{
- SourceFile* sourceFile = new SourceFile(this, pathInfo, blob->getBufferSize());
- m_sourceFiles.add(sourceFile);
- sourceFile->setContents(blob);
- return sourceFile;
-}
-
-SourceView* SourceManager::createSourceView(SourceFile* sourceFile, const PathInfo* pathInfo)
-{
- SourceRange range = allocateSourceRange(sourceFile->getContentSize());
-
- SourceView* sourceView = nullptr;
- if (pathInfo &&
- (pathInfo->foundPath.getLength() && sourceFile->getPathInfo().foundPath != pathInfo->foundPath))
- {
- sourceView = new SourceView(sourceFile, range, &pathInfo->foundPath);
- }
- else
- {
- sourceView = new SourceView(sourceFile, range, nullptr);
- }
-
- m_sourceViews.add(sourceView);
-
- return sourceView;
-}
-
-SourceView* SourceManager::findSourceView(SourceLoc loc) const
-{
- Index hi = m_sourceViews.getCount();
- // It must be in the range of this manager and have associated views for it to possibly be a hit
- if (!getSourceRange().contains(loc) || hi == 0)
- {
- return nullptr;
- }
-
- // If we don't have very many, we may as well just linearly search
- if (hi <= 8)
- {
- for (int i = 0; i < hi; ++i)
- {
- SourceView* view = m_sourceViews[i];
- if (view->getRange().contains(loc))
- {
- return view;
- }
- }
- return nullptr;
- }
-
- const SourceLoc::RawValue rawLoc = loc.getRaw();
-
- // Binary chop to see if we can find the associated SourceUnit
- Index lo = 0;
- while (lo + 1 < hi)
- {
- Index mid = (hi + lo) >> 1;
-
- SourceView* midView = m_sourceViews[mid];
- if (midView->getRange().contains(loc))
- {
- return midView;
- }
-
- const SourceLoc::RawValue midValue = midView->getRange().begin.getRaw();
- if (midValue <= rawLoc)
- {
- // The location we seek is at or after this entry
- lo = mid;
- }
- else
- {
- // The location we seek is before this entry
- hi = mid;
- }
- }
-
- // Check if low is actually a hit
- SourceView* view = m_sourceViews[lo];
- return (view->getRange().contains(loc)) ? view : nullptr;
-}
-
-SourceView* SourceManager::findSourceViewRecursively(SourceLoc loc) const
-{
- // Start with this manager
- const SourceManager* manager = this;
- do
- {
- SourceView* sourceView = manager->findSourceView(loc);
- // If we found a hit we are done
- if (sourceView)
- {
- return sourceView;
- }
- // Try the parent
- manager = manager->m_parent;
- }
- while (manager);
- // Didn't find it
- return nullptr;
-}
-
-SourceFile* SourceManager::findSourceFile(const String& uniqueIdentity) const
-{
- SourceFile*const* filePtr = m_sourceFileMap.TryGetValue(uniqueIdentity);
- return (filePtr) ? *filePtr : nullptr;
-}
-
-SourceFile* SourceManager::findSourceFileRecursively(const String& uniqueIdentity) const
-{
- const SourceManager* manager = this;
- do
- {
- SourceFile* sourceFile = manager->findSourceFile(uniqueIdentity);
- if (sourceFile)
- {
- return sourceFile;
- }
- manager = manager->m_parent;
- } while (manager);
- return nullptr;
-}
-
-void SourceManager::addSourceFile(const String& uniqueIdentity, SourceFile* sourceFile)
-{
- SLANG_ASSERT(!findSourceFileRecursively(uniqueIdentity));
- m_sourceFileMap.Add(uniqueIdentity, sourceFile);
-}
-
-HumaneSourceLoc SourceManager::getHumaneLoc(SourceLoc loc, SourceLocType type)
-{
- SourceView* sourceView = findSourceViewRecursively(loc);
- if (sourceView)
- {
- return sourceView->getHumaneLoc(loc, type);
- }
- else
- {
- return HumaneSourceLoc();
- }
-}
-
-PathInfo SourceManager::getPathInfo(SourceLoc loc, SourceLocType type)
-{
- SourceView* sourceView = findSourceViewRecursively(loc);
- if (sourceView)
- {
- return sourceView->getPathInfo(loc, type);
- }
- else
- {
- return PathInfo::makeUnknown();
- }
-}
-
-} // namespace Slang