Skip to content

Commit c36c284

Browse files
authored
Split out loadTrees() functionality (#1544)
1 parent 331ca18 commit c36c284

File tree

2 files changed

+83
-64
lines changed

2 files changed

+83
-64
lines changed

include/slang/driver/SourceLoader.h

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@
1010
#include <deque>
1111
#include <filesystem>
1212
#include <memory>
13-
#include <mutex>
1413
#include <optional>
1514
#include <span>
1615
#include <vector>
@@ -19,6 +18,7 @@
1918
#include "slang/text/Glob.h"
2019
#include "slang/text/SourceLocation.h"
2120
#include "slang/util/FlatMap.h"
21+
#include "slang/util/Function.h"
2222
#include "slang/util/Util.h"
2323

2424
namespace slang {
@@ -152,6 +152,16 @@ class SLANG_EXPORT SourceLoader {
152152
/// it does not exist. Returns nullptr if @a name is empty.
153153
SourceLibrary* getOrAddLibrary(std::string_view name);
154154

155+
/// Find a source buffer by searching through libraries added via -y
156+
SourceBuffer findBuffer(std::string_view name) const;
157+
158+
/// Load trees using a custom buffer finder function
159+
/// Result is stored in the same syntaxTree list
160+
static void loadTrees(
161+
SyntaxTreeList& syntaxTrees, function_ref<SourceBuffer(std::string_view)> findBufferFunc,
162+
SourceManager& sourceManager, const Bag& optionBag,
163+
std::span<const syntax::DefineDirectiveSyntax* const> inheritedMacros = {});
164+
155165
private:
156166
// One entry per unit of files + options to compile them.
157167
// Only used for addSeparateUnit.

source/driver/SourceLoader.cpp

Lines changed: 72 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -184,6 +184,26 @@ std::vector<SourceBuffer> SourceLoader::loadSources() {
184184
return results;
185185
}
186186

187+
SourceBuffer SourceLoader::findBuffer(std::string_view name) const {
188+
for (auto& dir : searchDirectories) {
189+
fs::path path(dir);
190+
path /= name;
191+
192+
for (auto& ext : searchExtensions) {
193+
path.replace_extension(ext);
194+
if (!sourceManager.isCached(path)) {
195+
// This file is never part of a library because if
196+
// it was we would have already loaded it earlier.
197+
auto readResult = sourceManager.readSource(path, /* library */ nullptr);
198+
if (readResult) {
199+
return *readResult;
200+
}
201+
}
202+
}
203+
}
204+
return {};
205+
}
206+
187207
SourceLoader::SyntaxTreeList SourceLoader::loadAndParseSources(const Bag& optionBag) {
188208
SyntaxTreeList syntaxTrees;
189209
std::vector<SourceBuffer> singleUnitBuffers;
@@ -332,76 +352,65 @@ SourceLoader::SyntaxTreeList SourceLoader::loadAndParseSources(const Bag& option
332352
}
333353

334354
if (!searchDirectories.empty()) {
335-
// If library directories are specified, see if we have any unknown instantiations
336-
// or package names for which we should search for additional source files to load.
337-
flat_hash_set<std::string_view> knownNames;
338-
auto addKnownNames = [&](const std::shared_ptr<SyntaxTree>& tree) {
339-
auto& meta = tree->getMetadata();
340-
meta.visitDeclaredSymbols([&](std::string_view name) { knownNames.emplace(name); });
341-
};
342-
343-
auto findMissingNames = [&](const std::shared_ptr<SyntaxTree>& tree,
344-
flat_hash_set<std::string_view>& missing) {
345-
auto& meta = tree->getMetadata();
346-
meta.visitReferencedSymbols([&](std::string_view name) {
347-
if (knownNames.find(name) == knownNames.end())
348-
missing.emplace(name);
349-
});
350-
};
351-
352-
for (auto& tree : syntaxTrees)
353-
addKnownNames(tree);
354-
355-
flat_hash_set<std::string_view> missingNames;
356-
for (auto& tree : syntaxTrees)
357-
findMissingNames(tree, missingNames);
358-
359-
// Keep loading new files as long as we are making forward progress.
360-
flat_hash_set<std::string_view> nextMissingNames;
361-
while (true) {
362-
for (auto name : missingNames) {
363-
SourceBuffer buffer;
364-
for (auto& dir : searchDirectories) {
365-
fs::path path(dir);
366-
path /= name;
367-
368-
for (auto& ext : searchExtensions) {
369-
path.replace_extension(ext);
370-
if (!sourceManager.isCached(path)) {
371-
// This file is never part of a library because if
372-
// it was we would have already loaded it earlier.
373-
auto readResult = sourceManager.readSource(path, /* library */ nullptr);
374-
if (readResult) {
375-
buffer = *readResult;
376-
break;
377-
}
378-
}
379-
}
355+
loadTrees(
356+
syntaxTrees, [this](std::string_view name) { return findBuffer(name); }, sourceManager,
357+
optionBag, inheritedMacros);
358+
}
380359

381-
if (buffer)
382-
break;
383-
}
360+
return syntaxTrees;
361+
}
384362

385-
if (buffer) {
386-
auto tree = SyntaxTree::fromBuffer(buffer, sourceManager, optionBag,
387-
inheritedMacros);
388-
tree->isLibraryUnit = true;
389-
syntaxTrees.emplace_back(tree);
363+
void SourceLoader::loadTrees(
364+
SyntaxTreeList& syntaxTrees, function_ref<SourceBuffer(std::string_view)> findBufferFunc,
365+
SourceManager& sourceManager, const Bag& optionBag,
366+
std::span<const syntax::DefineDirectiveSyntax* const> inheritedMacros) {
367+
// If library directories are specified, see if we have any unknown instantiations
368+
// or package names for which we should search for additional source files to load.
369+
flat_hash_set<std::string_view> knownNames;
370+
auto addKnownNames = [&](const std::shared_ptr<syntax::SyntaxTree>& tree) {
371+
auto& meta = tree->getMetadata();
372+
meta.visitDeclaredSymbols([&](std::string_view name) { knownNames.emplace(name); });
373+
};
390374

391-
addKnownNames(tree);
392-
findMissingNames(tree, nextMissingNames);
393-
}
394-
}
375+
auto findMissingNames = [&](const std::shared_ptr<syntax::SyntaxTree>& tree,
376+
flat_hash_set<std::string_view>& missing) {
377+
auto& meta = tree->getMetadata();
378+
meta.visitReferencedSymbols([&](std::string_view name) {
379+
if (knownNames.find(name) == knownNames.end())
380+
missing.emplace(name);
381+
});
382+
};
395383

396-
if (nextMissingNames.empty())
397-
break;
384+
for (auto& tree : syntaxTrees)
385+
addKnownNames(tree);
398386

399-
missingNames = std::move(nextMissingNames);
400-
nextMissingNames = {};
387+
flat_hash_set<std::string_view> missingNames;
388+
for (auto& tree : syntaxTrees)
389+
findMissingNames(tree, missingNames);
390+
391+
// Keep loading new files as long as we are making forward progress.
392+
flat_hash_set<std::string_view> nextMissingNames;
393+
while (true) {
394+
for (auto name : missingNames) {
395+
auto buffer = findBufferFunc(name);
396+
397+
if (buffer) {
398+
auto tree = syntax::SyntaxTree::fromBuffer(buffer, sourceManager, optionBag,
399+
inheritedMacros);
400+
tree->isLibraryUnit = true;
401+
syntaxTrees.emplace_back(tree);
402+
403+
addKnownNames(tree);
404+
findMissingNames(tree, nextMissingNames);
405+
}
401406
}
402-
}
403407

404-
return syntaxTrees;
408+
if (nextMissingNames.empty())
409+
break;
410+
411+
missingNames = std::move(nextMissingNames);
412+
nextMissingNames = {};
413+
}
405414
}
406415

407416
SourceLibrary* SourceLoader::getOrAddLibrary(std::string_view name) {

0 commit comments

Comments
 (0)