Skip to content

Commit

Permalink
Add an option to change the name of the default library
Browse files Browse the repository at this point in the history
  • Loading branch information
MikePopoloski committed Feb 23, 2024
1 parent fb1e901 commit 80d0a3c
Show file tree
Hide file tree
Showing 10 changed files with 93 additions and 32 deletions.
4 changes: 4 additions & 0 deletions docs/command-line-ref.dox
Original file line number Diff line number Diff line change
Expand Up @@ -221,6 +221,10 @@ ones later in the list.
If no explicit ordering is given the default order is
the order in which the libraries are specified to the tool.

`--defaultLibName <name>`

Sets the name of the default library. If not set, defaults to "work".

`--max-hierarchy-depth <depth>`

Set the maximum depth of the design hierarchy. Used to detect infinite
Expand Down
10 changes: 4 additions & 6 deletions include/slang/ast/Compilation.h
Original file line number Diff line number Diff line change
Expand Up @@ -185,9 +185,6 @@ struct SLANG_EXPORT CompilationOptions {
/// A list of library names, in the order in which they should be searched
/// when binding cells to instances.
std::vector<std::string> defaultLiblist;

/// The name of the default library.
std::string defaultLibName = "work";
};

/// A node in a tree representing an instance in the design
Expand Down Expand Up @@ -234,7 +231,7 @@ struct HierarchyOverrideNode {
class SLANG_EXPORT Compilation : public BumpAllocator {
public:
/// Constructs a new instance of the Compilation class.
explicit Compilation(const Bag& options = {});
explicit Compilation(const Bag& options = {}, const SourceLibrary* defaultLib = nullptr);
Compilation(const Compilation& other) = delete;
Compilation(Compilation&& other) = delete;
~Compilation();
Expand Down Expand Up @@ -318,7 +315,7 @@ class SLANG_EXPORT Compilation : public BumpAllocator {
const SourceLibrary* getSourceLibrary(std::string_view name) const;

/// Gets the default library object.
const SourceLibrary& getDefaultLibrary() const { return *defaultLib; }
const SourceLibrary& getDefaultLibrary() const { return *defaultLibPtr; }

/// Gets the definition with the given name, or nullptr if there is no such definition.
/// This takes into account the given scope so that nested definitions are found
Expand Down Expand Up @@ -891,7 +888,8 @@ class SLANG_EXPORT Compilation : public BumpAllocator {
const PackageSymbol* stdPkg = nullptr;

// The default library.
std::unique_ptr<SourceLibrary> defaultLib;
std::unique_ptr<SourceLibrary> defaultLibMem;
const SourceLibrary* defaultLibPtr;
};

} // namespace slang::ast
5 changes: 4 additions & 1 deletion include/slang/driver/Driver.h
Original file line number Diff line number Diff line change
Expand Up @@ -163,6 +163,9 @@ class SLANG_EXPORT Driver {
/// should be resolved between libraries.
std::vector<std::string> libraryOrder;

/// The name of the default library; if not set, defaults to "work".
std::optional<std::string> defaultLibName;

/// @}
/// @name Diagnostics control
/// @{
Expand Down Expand Up @@ -287,7 +290,7 @@ class SLANG_EXPORT Driver {
[[nodiscard]] Bag createOptionBag() const;

/// Creates a compilation object from all of the current loaded state of the driver.
[[nodiscard]] std::unique_ptr<ast::Compilation> createCompilation() const;
[[nodiscard]] std::unique_ptr<ast::Compilation> createCompilation();

/// Reports all parsing diagnostics found in all of the @a syntaxTrees
/// @returns true on success and false if errors were encountered.
Expand Down
5 changes: 4 additions & 1 deletion include/slang/driver/SourceLoader.h
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,10 @@ class SLANG_EXPORT SourceLoader {
/// Gets the list of errors that have occurred while loading files.
std::span<const std::string> getErrors() const { return errors; }

/// Gets a pointer to the source library with the given name, or adds it if
/// it does not exist. Returns nullptr if @a name is empty.
SourceLibrary* getOrAddLibrary(std::string_view name);

private:
// One entry per unit of files + options to compile them.
// Only used for addSeparateUnit.
Expand Down Expand Up @@ -196,7 +200,6 @@ class SLANG_EXPORT SourceLoader {
std::pair<const FileEntry*, std::error_code>,
std::pair<SourceBuffer, const UnitEntry*>>;

SourceLibrary* getOrAddLibrary(std::string_view name);
void addFilesInternal(std::string_view pattern, const std::filesystem::path& basePath,
bool isLibraryFile, const SourceLibrary* library, const UnitEntry* unit,
bool expandEnvVars);
Expand Down
5 changes: 4 additions & 1 deletion include/slang/text/SourceLocation.h
Original file line number Diff line number Diff line change
Expand Up @@ -192,11 +192,14 @@ struct SLANG_EXPORT SourceLibrary {
/// search order. Lower numbers are higher priority.
int priority = 0;

/// Set to true if this is the default library.
bool isDefault = false;

/// Default constructor.
SourceLibrary() = default;

/// Constructs a new source library object with the given name.
SourceLibrary(std::string name, int priority) : name(std::move(name)), priority(priority) {}
SourceLibrary(std::string&& name, int priority) : name(std::move(name)), priority(priority) {}
};

/// Represents a source buffer; that is, the actual text of the source
Expand Down
44 changes: 25 additions & 19 deletions source/ast/Compilation.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -46,9 +46,9 @@ const PackageSymbol& createStdPackage(Compilation&);

namespace slang::ast {

Compilation::Compilation(const Bag& options) :
Compilation::Compilation(const Bag& options, const SourceLibrary* defaultLib) :
options(options.getOrDefault<CompilationOptions>()), driverMapAllocator(*this),
unrollIntervalMapAllocator(*this), tempDiag({}, {}) {
unrollIntervalMapAllocator(*this), tempDiag({}, {}), defaultLibPtr(defaultLib) {

// Construct all built-in types.
bitType = emplace<ScalarType>(ScalarType::Bit);
Expand Down Expand Up @@ -161,8 +161,15 @@ Compilation::Compilation(const Bag& options) :
builtins::registerGateTypes(*this);

// Register the default library.
defaultLib = std::make_unique<SourceLibrary>(this->options.defaultLibName, INT_MAX);
libraryNameMap[defaultLib->name] = defaultLib.get();
if (defaultLibPtr) {
SLANG_ASSERT(defaultLibPtr->isDefault);
}
else {
defaultLibMem = std::make_unique<SourceLibrary>("work"s, INT_MAX);
defaultLibMem->isDefault = true;
defaultLibPtr = defaultLibMem.get();
libraryNameMap[defaultLibPtr->name] = defaultLibPtr;
}

// Set a default handler for printing types and symbol paths, for convenience.
static std::once_flag onceFlag;
Expand Down Expand Up @@ -201,10 +208,14 @@ void Compilation::addSyntaxTree(std::shared_ptr<SyntaxTree> tree) {
}

auto lib = tree->getSourceLibrary();
if (lib)
libraryNameMap[lib->name] = lib;
else
lib = defaultLib.get();
if (lib) {
auto& entry = libraryNameMap[lib->name];
SLANG_ASSERT(entry == nullptr || entry == lib);
entry = lib;
}
else {
lib = defaultLibPtr;
}

const SyntaxNode& node = tree->root();
const SyntaxNode* topNode = &node;
Expand Down Expand Up @@ -359,7 +370,7 @@ const RootSymbol& Compilation::getRoot(bool skipDefParamsAndBinds) {
continue;

auto& def = defSym->as<DefinitionSymbol>();
if (&def.sourceLibrary != defaultLib.get() ||
if (!def.sourceLibrary.isDefault ||
globalInstantiations.find(def.name) != globalInstantiations.end()) {
continue;
}
Expand Down Expand Up @@ -399,14 +410,9 @@ const RootSymbol& Compilation::getRoot(bool skipDefParamsAndBinds) {

// If this definition is in a library, it can only be targeted as
// a top module by the user including the library name in the string.
flat_hash_set<std::string_view>::iterator it;
if (&def.sourceLibrary != defaultLib.get()) {
auto target = fmt::format("{}.{}", def.sourceLibrary.name, def.name);
it = tm.find(target);
}
else {
auto it = tm.find(fmt::format("{}.{}", def.sourceLibrary.name, def.name));
if (it == tm.end() && def.sourceLibrary.isDefault)
it = tm.find(def.name);
}

if (it != tm.end()) {
// Remove from the top modules set so that we know we visited it.
Expand All @@ -428,7 +434,7 @@ const RootSymbol& Compilation::getRoot(bool skipDefParamsAndBinds) {
// Otherwise this definition might be unreferenced and not automatically
// instantiated (don't add library definitions to this list though).
if (globalInstantiations.find(def.name) == globalInstantiations.end() &&
&def.sourceLibrary == defaultLib.get()) {
def.sourceLibrary.isDefault) {
unreferencedDefs.push_back(&def);
}
}
Expand Down Expand Up @@ -457,7 +463,7 @@ const RootSymbol& Compilation::getRoot(bool skipDefParamsAndBinds) {
auto lib = conf->getSourceLibrary();
SLANG_ASSERT(lib);

if (lib->name == confLib || (confLib.empty() && lib == defaultLib.get())) {
if (lib->name == confLib || (confLib.empty() && lib->isDefault)) {
foundConf = conf;
break;
}
Expand Down Expand Up @@ -2325,7 +2331,7 @@ std::pair<const Symbol*, bool> Compilation::resolveConfigRules(
return {nullptr, true};
}

const SourceLibrary* overrideLib = defaultLib.get();
const SourceLibrary* overrideLib = defaultLibPtr;
if (id.lib.empty()) {
if (auto parentDef = scope.asSymbol().getDeclaringDefinition())
overrideLib = &parentDef->sourceLibrary;
Expand Down
4 changes: 4 additions & 0 deletions source/ast/Symbol.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -254,6 +254,10 @@ const SourceLibrary* Symbol::getSourceLibrary() const {
return &curr->as<DefinitionSymbol>().sourceLibrary;
case SymbolKind::CompilationUnit:
return &curr->as<CompilationUnitSymbol>().sourceLibrary;
case SymbolKind::InstanceBody:
return &curr->as<InstanceBodySymbol>().getDefinition().sourceLibrary;
case SymbolKind::Instance:
return &curr->as<InstanceSymbol>().getDefinition().sourceLibrary;
default:
auto scope = curr->getParentScope();
if (!scope)
Expand Down
2 changes: 1 addition & 1 deletion source/ast/symbols/CompilationUnitSymbols.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -352,7 +352,7 @@ void DefinitionSymbol::serializeTo(ASTSerializer& serializer) const {
auto scope = getParentScope();
SLANG_ASSERT(scope);

if (&sourceLibrary != &scope->getCompilation().getDefaultLibrary())
if (!sourceLibrary.isDefault)
serializer.write("sourceLibrary", sourceLibrary.name);
}

Expand Down
15 changes: 13 additions & 2 deletions source/driver/Driver.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -186,6 +186,8 @@ void Driver::addStandardArgs() {
cmdLine.add("-L", options.libraryOrder,
"A list of library names that controls the priority order for module lookup",
"<library>", CommandLineFlags::CommaList);
cmdLine.add("--defaultLibName", options.defaultLibName, "Sets the name of the default library",
"<name>");

// Diagnostics control
cmdLine.add("-W", options.warningOptions, "Control the specified warning", "<warning>");
Expand Down Expand Up @@ -732,8 +734,17 @@ void Driver::addCompilationOptions(Bag& bag) const {
bag.set(coptions);
}

std::unique_ptr<Compilation> Driver::createCompilation() const {
auto compilation = std::make_unique<Compilation>(createOptionBag());
std::unique_ptr<Compilation> Driver::createCompilation() {
SourceLibrary* defaultLib;
if (options.defaultLibName && !options.defaultLibName->empty())
defaultLib = sourceLoader.getOrAddLibrary(*options.defaultLibName);
else
defaultLib = sourceLoader.getOrAddLibrary("work");

SLANG_ASSERT(defaultLib);
defaultLib->isDefault = true;

auto compilation = std::make_unique<Compilation>(createOptionBag(), defaultLib);
for (auto& tree : sourceLoader.getLibraryMaps())
compilation->addSyntaxTree(tree);
for (auto& tree : syntaxTrees)
Expand Down
31 changes: 30 additions & 1 deletion tests/unittests/DriverTests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -636,7 +636,7 @@ TEST_CASE("Driver separate unit listing") {

auto& root = compilation->getRoot();
REQUIRE(root.topInstances.size() == 1);
CHECK(root.topInstances[0]->getSourceLibrary() == nullptr);
CHECK(root.topInstances[0]->getSourceLibrary()->name == "work");
CHECK(root.topInstances[0]->name == "k");

auto units = compilation->getCompilationUnits();
Expand All @@ -653,3 +653,32 @@ TEST_CASE("Driver separate unit listing") {
});
CHECK(it != defs.end());
}

TEST_CASE("Driver customize default lib name") {
auto guard = OS::captureOutput();

Driver driver;
driver.addStandardArgs();

auto args = fmt::format("testfoo \"{0}test5.sv\" -v \"blah={0}test6.sv\" --defaultLibName blah",
findTestDir());
CHECK(driver.parseCommandLine(args));
CHECK(driver.processOptions());
CHECK(driver.parseAllSources());

auto compilation = driver.createCompilation();
CHECK(driver.reportCompilation(*compilation, false));
CHECK(stdoutContains("Build succeeded"));

auto& root = compilation->getRoot();
REQUIRE(root.topInstances.size() == 1);
CHECK(root.topInstances[0]->getSourceLibrary()->name == "blah");
CHECK(root.topInstances[0]->name == "k");

auto units = compilation->getCompilationUnits();
REQUIRE(units.size() == 2);
REQUIRE(units[0]->getSourceLibrary() != nullptr);
REQUIRE(units[1]->getSourceLibrary() != nullptr);
CHECK(units[0]->getSourceLibrary()->name == "blah");
CHECK(units[1]->getSourceLibrary()->name == "blah");
}

0 comments on commit 80d0a3c

Please sign in to comment.