diff --git a/include/slang/driver/SourceLoader.h b/include/slang/driver/SourceLoader.h index f84868bb3..c80964add 100644 --- a/include/slang/driver/SourceLoader.h +++ b/include/slang/driver/SourceLoader.h @@ -17,6 +17,7 @@ #include "slang/syntax/SyntaxFwd.h" #include "slang/text/Glob.h" +#include "slang/text/SourceLocation.h" #include "slang/util/Hash.h" #include "slang/util/Util.h" @@ -66,6 +67,9 @@ class SLANG_EXPORT SourceLoader { SourceLoader(const SourceLoader& other) = delete; SourceLoader(SourceLoader&& other) = default; + /// @brief Adds a pre-loaded buffer + void addBuffer(SourceBuffer buffer); + /// @brief Adds files to be loaded, specified via the given @a pattern. /// /// All of the files that match the pattern will be added for loading. @@ -159,6 +163,10 @@ class SLANG_EXPORT SourceLoader { // The filesystem path (as specified by the user). std::filesystem::path path; + // An optional pre-loaded buffer for when the source doesn't originate + // from the filesystem + SourceBuffer preloadedBuffer; + // The library to which the file belongs, if any. const SourceLibrary* library = nullptr; @@ -186,8 +194,11 @@ class SLANG_EXPORT SourceLoader { FileEntry(std::filesystem::path&& path, bool isLibraryFile, const SourceLibrary* library, const UnitEntry* unit, GlobRank libraryRank) : - path(std::move(path)), library(library), unit(unit), libraryRank(libraryRank), - isLibraryFile(isLibraryFile) {} + path(std::move(path)), preloadedBuffer(), library(library), unit(unit), + libraryRank(libraryRank), isLibraryFile(isLibraryFile) {} + + FileEntry(SourceBuffer buffer) : + preloadedBuffer(buffer), libraryRank(GlobRank::ExactPath) {} }; // The result of a loadAndParse call. diff --git a/source/driver/SourceLoader.cpp b/source/driver/SourceLoader.cpp index a2fd7506b..a006b6d88 100644 --- a/source/driver/SourceLoader.cpp +++ b/source/driver/SourceLoader.cpp @@ -31,6 +31,10 @@ SourceLoader::SourceLoader(SourceManager& sourceManager) : sourceManager(sourceM searchExtensions.emplace_back(ext); } +void SourceLoader::addBuffer(SourceBuffer buffer) { + fileEntries.emplace_back(buffer); +} + void SourceLoader::addFiles(std::string_view pattern) { addFilesInternal(pattern, {}, /* isLibraryFile */ false, /* library */ nullptr, /* unit */ nullptr, @@ -157,7 +161,12 @@ std::vector SourceLoader::loadSources() { results.reserve(fileEntries.size()); for (auto& entry : fileEntries) { - auto buffer = sourceManager.readSource(entry.path, entry.library); + SourceManager::BufferOrError buffer; + if (!entry.preloadedBuffer) + buffer = sourceManager.readSource(entry.path, entry.library); + else + buffer = entry.preloadedBuffer; + if (!buffer) addError(entry.path, buffer.error()); else @@ -527,7 +536,12 @@ SourceLoader::LoadResult SourceLoader::loadAndParse(const FileEntry& entry, cons uint64_t fileSortKey) { // TODO: error if secondLib is set - auto buffer = sourceManager.readSource(entry.path, entry.library, fileSortKey); + SourceManager::BufferOrError buffer; + if (entry.preloadedBuffer) + buffer = entry.preloadedBuffer; + else + buffer = sourceManager.readSource(entry.path, entry.library, fileSortKey); + if (!buffer) return std::pair{&entry, buffer.error()};