Skip to content

Commit

Permalink
Require all sources in a compilation unit to be from the same library…
Browse files Browse the repository at this point in the history
…, unify how AST elements find source library
  • Loading branch information
MikePopoloski committed Dec 31, 2023
1 parent b1f6be1 commit d33f06c
Show file tree
Hide file tree
Showing 17 changed files with 101 additions and 109 deletions.
1 change: 1 addition & 0 deletions bindings/python/SymbolBindings.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,7 @@ void registerSymbols(py::module_& m) {
.def_property_readonly("declaringDefinition", &Symbol::getDeclaringDefinition)
.def_property_readonly("randMode", &Symbol::getRandMode)
.def_property_readonly("nextSibling", &Symbol::getNextSibling)
.def_property_readonly("sourceLibrary", &Symbol::getSourceLibrary)
.def_property_readonly("hierarchicalPath",
[](const Symbol& self) {
std::string str;
Expand Down
3 changes: 2 additions & 1 deletion bindings/python/SyntaxBindings.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -180,7 +180,7 @@ void registerSyntax(py::module_& m) {
.def("__str__", &SyntaxNode::toString);

py::class_<SyntaxTree, std::shared_ptr<SyntaxTree>>(m, "SyntaxTree")
.def_readonly("isLibrary", &SyntaxTree::isLibrary)
.def_readonly("isLibraryUnit", &SyntaxTree::isLibraryUnit)
.def_static(
"fromFile",
[](std::string_view path) {
Expand Down Expand Up @@ -244,6 +244,7 @@ void registerSyntax(py::module_& m) {
.def_property_readonly("sourceManager", py::overload_cast<>(&SyntaxTree::sourceManager))
.def_property_readonly("root", py::overload_cast<>(&SyntaxTree::root))
.def_property_readonly("options", &SyntaxTree::options)
.def_property_readonly("sourceLibrary", &SyntaxTree::getSourceLibrary)
.def_static("getDefaultSourceManager", &SyntaxTree::getDefaultSourceManager, byref);

py::class_<LexerOptions>(m, "LexerOptions")
Expand Down
4 changes: 1 addition & 3 deletions include/slang/ast/Compilation.h
Original file line number Diff line number Diff line change
Expand Up @@ -628,8 +628,7 @@ class SLANG_EXPORT Compilation : public BumpAllocator {
}

/// Allocates a config block symbol.
ConfigBlockSymbol* allocConfigBlock(std::string_view name, SourceLocation loc,
const SourceLibrary* sourceLibrary);
ConfigBlockSymbol* allocConfigBlock(std::string_view name, SourceLocation loc);

/// Gets the driver map allocator.
DriverIntervalMap::allocator_type& getDriverMapAllocator() { return driverMapAllocator; }
Expand Down Expand Up @@ -751,7 +750,6 @@ class SLANG_EXPORT Compilation : public BumpAllocator {

struct SyntaxMetadata {
const syntax::SyntaxTree* tree = nullptr;
const SourceLibrary* library = nullptr;
const NetType* defaultNetType = nullptr;
std::optional<TimeScale> timeScale;
UnconnectedDrive unconnectedDrive = UnconnectedDrive::None;
Expand Down
15 changes: 6 additions & 9 deletions include/slang/ast/symbols/CompilationUnitSymbols.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,9 @@ class Type;
class SLANG_EXPORT CompilationUnitSymbol : public Symbol, public Scope {
public:
std::optional<TimeScale> timeScale;
const SourceLibrary* sourceLibrary;

explicit CompilationUnitSymbol(Compilation& compilation);
CompilationUnitSymbol(Compilation& compilation, const SourceLibrary* sourceLibrary);

void addMembers(const syntax::SyntaxNode& syntax);

Expand Down Expand Up @@ -192,7 +193,7 @@ class SLANG_EXPORT DefinitionSymbol : public Symbol {
DefinitionSymbol(const Scope& scope, LookupLocation lookupLocation,
const syntax::ModuleDeclarationSyntax& syntax, const NetType& defaultNetType,
UnconnectedDrive unconnectedDrive, std::optional<TimeScale> directiveTimeScale,
const syntax::SyntaxTree* syntaxTree, const SourceLibrary* sourceLibrary);
const syntax::SyntaxTree* syntaxTree);

/// Returns a string description of the definition kind, such as "module",
/// "interface", or "program".
Expand Down Expand Up @@ -255,20 +256,16 @@ class SLANG_EXPORT ConfigBlockSymbol : public Symbol, public Scope {
ConfigRule rule;
};

const SourceLibrary* sourceLibrary;
std::span<const ConfigCellId> topCells;
std::span<const SourceLibrary* const> defaultLiblist;
std::span<const InstanceOverride> instanceOverrides;
flat_hash_map<std::string_view, std::vector<CellOverride>> cellOverrides;

ConfigBlockSymbol(Compilation& compilation, std::string_view name, SourceLocation loc,
const SourceLibrary* sourceLibrary) :
Symbol(SymbolKind::ConfigBlock, name, loc),
Scope(compilation, this), sourceLibrary(sourceLibrary) {}
ConfigBlockSymbol(Compilation& compilation, std::string_view name, SourceLocation loc) :
Symbol(SymbolKind::ConfigBlock, name, loc), Scope(compilation, this) {}

static ConfigBlockSymbol& fromSyntax(const Scope& scope,
const syntax::ConfigDeclarationSyntax& syntax,
const SourceLibrary* sourceLibrary);
const syntax::ConfigDeclarationSyntax& syntax);

void serializeTo(ASTSerializer& serialize) const;

Expand Down
8 changes: 3 additions & 5 deletions include/slang/ast/symbols/MemberSymbols.h
Original file line number Diff line number Diff line change
Expand Up @@ -268,21 +268,19 @@ class SLANG_EXPORT PrimitiveSymbol : public Symbol, public Scope {
TableField output;
};

const SourceLibrary* sourceLibrary;
std::span<const PrimitivePortSymbol* const> ports;
std::span<const TableEntry> table;
const ConstantValue* initVal = nullptr;
bool isSequential = false;
enum PrimitiveKind { UserDefined, Fixed, NInput, NOutput } primitiveKind;

PrimitiveSymbol(Compilation& compilation, std::string_view name, SourceLocation loc,
PrimitiveKind primitiveKind, const SourceLibrary* sourceLibrary) :
PrimitiveKind primitiveKind) :
Symbol(SymbolKind::Primitive, name, loc),
Scope(compilation, this), sourceLibrary(sourceLibrary), primitiveKind(primitiveKind) {}
Scope(compilation, this), primitiveKind(primitiveKind) {}

static PrimitiveSymbol& fromSyntax(const Scope& scope,
const syntax::UdpDeclarationSyntax& syntax,
const SourceLibrary* sourceLibrary);
const syntax::UdpDeclarationSyntax& syntax);

void serializeTo(ASTSerializer& serializer) const;

Expand Down
3 changes: 1 addition & 2 deletions include/slang/parsing/ParserMetadata.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@ namespace slang::parsing {
struct SLANG_EXPORT ParserMetadata {
/// Collection of metadata that can be associated with a syntax node at parse time.
struct Node {
const SourceLibrary* library = nullptr;
TokenKind defaultNetType;
TokenKind unconnectedDrive;
std::optional<TimeScale> timeScale;
Expand Down Expand Up @@ -59,7 +58,7 @@ struct SLANG_EXPORT ParserMetadata {
bool hasBindDirectives = false;

/// Constructs a new set of parser metadata by walking the provided syntax tree.
static ParserMetadata fromSyntax(const syntax::SyntaxNode& root, const SourceLibrary* library);
static ParserMetadata fromSyntax(const syntax::SyntaxNode& root);
};

} // namespace slang::parsing
10 changes: 7 additions & 3 deletions include/slang/syntax/SyntaxTree.h
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ class SLANG_EXPORT SyntaxTree {

/// Indicates whether this syntax tree represents a "library" compilation unit,
/// which means that modules declared within it are not automatically instantiated.
bool isLibrary = false;
bool isLibraryUnit = false;

SyntaxTree(SyntaxNode* root, SourceManager& sourceManager, BumpAllocator&& alloc,
const SourceLibrary* library, std::shared_ptr<SyntaxTree> parent = nullptr);
Expand Down Expand Up @@ -181,6 +181,9 @@ class SLANG_EXPORT SyntaxTree {
/// Gets the source manager used to build the syntax tree.
const SourceManager& sourceManager() const { return sourceMan; }

/// Gets the source library with which the syntax tree is associated.
const SourceLibrary* getSourceLibrary() const { return library; }

/// Gets the root of the syntax tree.
SyntaxNode& root() { return *rootNode; }

Expand Down Expand Up @@ -209,8 +212,8 @@ class SLANG_EXPORT SyntaxTree {
static SourceManager& getDefaultSourceManager();

private:
SyntaxTree(SyntaxNode* root, SourceManager& sourceManager, BumpAllocator&& alloc,
Diagnostics&& diagnostics, parsing::ParserMetadata&& metadata,
SyntaxTree(SyntaxNode* root, const SourceLibrary* library, SourceManager& sourceManager,
BumpAllocator&& alloc, Diagnostics&& diagnostics, parsing::ParserMetadata&& metadata,
std::vector<const DefineDirectiveSyntax*>&& macros, Bag options);

static std::shared_ptr<SyntaxTree> create(SourceManager& sourceManager,
Expand All @@ -219,6 +222,7 @@ class SLANG_EXPORT SyntaxTree {
bool guess);

SyntaxNode* rootNode;
const SourceLibrary* library;
SourceManager& sourceMan;
BumpAllocator alloc;
Diagnostics diagnosticsBuffer;
Expand Down
35 changes: 15 additions & 20 deletions source/ast/Compilation.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -196,20 +196,22 @@ void Compilation::addSyntaxTree(std::shared_ptr<SyntaxTree> tree) {
}
}

if (auto lib = tree->getSourceLibrary())
libraryNameMap[lib->name] = lib;

const SyntaxNode& node = tree->root();
const SyntaxNode* topNode = &node;
while (topNode->parent)
topNode = topNode->parent;

auto unit = emplace<CompilationUnitSymbol>(*this);
auto unit = emplace<CompilationUnitSymbol>(*this, tree->getSourceLibrary());
unit->setSyntax(*topNode);
root->addMember(*unit);
compilationUnits.push_back(unit);

for (auto& [n, meta] : tree->getMetadata().nodeMap) {
SyntaxMetadata result;
result.tree = tree.get();
result.library = meta.library;
result.defaultNetType = &getNetType(meta.defaultNetType);
result.timeScale = meta.timeScale;

Expand All @@ -226,8 +228,6 @@ void Compilation::addSyntaxTree(std::shared_ptr<SyntaxTree> tree) {
}

syntaxMetadata[n] = result;
if (result.library)
libraryNameMap[result.library->name] = result.library;
}

for (auto& name : tree->getMetadata().globalInstances)
Expand Down Expand Up @@ -358,7 +358,7 @@ const RootSymbol& Compilation::getRoot(bool skipDefParamsAndBinds) {
}

// Library definitions are never automatically instantiated in any capacity.
if (!def.syntaxTree || !def.syntaxTree->isLibrary) {
if (!def.syntaxTree || !def.syntaxTree->isLibraryUnit) {
if (def.definitionKind == DefinitionKind::Module ||
def.definitionKind == DefinitionKind::Program) {
if (isValidTop(def)) {
Expand Down Expand Up @@ -447,8 +447,8 @@ const RootSymbol& Compilation::getRoot(bool skipDefParamsAndBinds) {
if (auto confIt = configBlocks.find(confName); confIt != configBlocks.end()) {
const ConfigBlockSymbol* foundConf = nullptr;
for (auto conf : confIt->second) {
if ((!conf->sourceLibrary && confLib.empty()) ||
(conf->sourceLibrary && conf->sourceLibrary->name == confLib)) {
if ((!conf->getSourceLibrary() && confLib.empty()) ||
(conf->getSourceLibrary() && conf->getSourceLibrary()->name == confLib)) {
foundConf = conf;
break;
}
Expand All @@ -468,7 +468,7 @@ const RootSymbol& Compilation::getRoot(bool skipDefParamsAndBinds) {

auto& def = defSym->as<DefinitionSymbol>();
if ((cell.lib.empty() &&
def.sourceLibrary == foundConf->sourceLibrary) ||
def.sourceLibrary == foundConf->getSourceLibrary()) ||
(def.sourceLibrary && def.sourceLibrary->name == cell.lib)) {
foundDef = &def;
break;
Expand Down Expand Up @@ -757,7 +757,7 @@ void Compilation::createDefinition(const Scope& scope, LookupLocation location,
auto def = definitionMemory
.emplace_back(std::make_unique<DefinitionSymbol>(
scope, location, syntax, *metadata.defaultNetType, metadata.unconnectedDrive,
metadata.timeScale, metadata.tree, metadata.library))
metadata.timeScale, metadata.tree))
.get();
definitionFromSyntax[&syntax] = def;

Expand Down Expand Up @@ -906,16 +906,15 @@ const PackageSymbol& Compilation::createPackage(const Scope& scope,

const ConfigBlockSymbol& Compilation::createConfigBlock(const Scope& scope,
const ConfigDeclarationSyntax& syntax) {
auto& metadata = syntaxMetadata[&syntax];
auto& config = ConfigBlockSymbol::fromSyntax(scope, syntax, metadata.library);
auto& config = ConfigBlockSymbol::fromSyntax(scope, syntax);

auto it = configBlocks.find(config.name);
if (it == configBlocks.end()) {
configBlocks.emplace(config.name, std::vector<const ConfigBlockSymbol*>{&config});
}
else {
auto findIt = std::ranges::find_if(it->second, [&](const ConfigBlockSymbol* elem) {
return elem->sourceLibrary == config.sourceLibrary;
return elem->getSourceLibrary() == config.getSourceLibrary();
});

if (findIt != it->second.end()) {
Expand All @@ -933,11 +932,8 @@ const ConfigBlockSymbol& Compilation::createConfigBlock(const Scope& scope,

const PrimitiveSymbol& Compilation::createPrimitive(const Scope& scope,
const UdpDeclarationSyntax& syntax) {
// TODO: handle primitives in libraries
const SourceLibrary* sourceLibrary = nullptr;
auto& prim = PrimitiveSymbol::fromSyntax(scope, syntax, sourceLibrary);
auto& prim = PrimitiveSymbol::fromSyntax(scope, syntax);
insertDefinition(prim, scope);

return prim;
}

Expand Down Expand Up @@ -1260,7 +1256,7 @@ const NameSyntax& Compilation::tryParseName(std::string_view name, Diagnostics&
}

CompilationUnitSymbol& Compilation::createScriptScope() {
auto unit = emplace<CompilationUnitSymbol>(*this);
auto unit = emplace<CompilationUnitSymbol>(*this, nullptr);
root->addMember(*unit);
return *unit;
}
Expand Down Expand Up @@ -1580,9 +1576,8 @@ AssertionInstanceDetails* Compilation::allocAssertionDetails() {
return assertionDetailsAllocator.emplace();
}

ConfigBlockSymbol* Compilation::allocConfigBlock(std::string_view name, SourceLocation loc,
const SourceLibrary* sourceLibrary) {
return configBlockAllocator.emplace(*this, name, loc, sourceLibrary);
ConfigBlockSymbol* Compilation::allocConfigBlock(std::string_view name, SourceLocation loc) {
return configBlockAllocator.emplace(*this, name, loc);
}

const ImplicitTypeSyntax& Compilation::createEmptyTypeSyntax(SourceLocation loc) {
Expand Down
26 changes: 15 additions & 11 deletions source/ast/Symbol.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -247,17 +247,21 @@ const DefinitionSymbol* Symbol::getDeclaringDefinition() const {
}

const SourceLibrary* Symbol::getSourceLibrary() const {
switch (kind) {
case SymbolKind::Definition:
return as<DefinitionSymbol>().sourceLibrary;
case SymbolKind::Primitive:
return as<PrimitiveSymbol>().sourceLibrary;
case SymbolKind::ConfigBlock:
return as<ConfigBlockSymbol>().sourceLibrary;
default:
if (auto def = getDeclaringDefinition())
return def->sourceLibrary;
return nullptr;
auto curr = this;
while (true) {
switch (curr->kind) {
case SymbolKind::Definition:
return curr->as<DefinitionSymbol>().sourceLibrary;
case SymbolKind::CompilationUnit:
return curr->as<CompilationUnitSymbol>().sourceLibrary;
default:
auto scope = curr->getParentScope();
if (!scope)
return nullptr;

curr = &scope->asSymbol();
break;
}
}
}

Expand Down
2 changes: 1 addition & 1 deletion source/ast/builtins/GateTypes.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ namespace slang::ast::builtins {
static void gate(Compilation& c, std::string_view name,
std::initializer_list<PrimitivePortDirection> portDirs,
PrimitiveSymbol::PrimitiveKind primitiveKind = PrimitiveSymbol::Fixed) {
auto& prim = *c.emplace<PrimitiveSymbol>(c, name, NL, primitiveKind, nullptr);
auto& prim = *c.emplace<PrimitiveSymbol>(c, name, NL, primitiveKind);
c.addGateType(prim);

SmallVector<const PrimitivePortSymbol*> ports;
Expand Down
18 changes: 9 additions & 9 deletions source/ast/symbols/CompilationUnitSymbols.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,14 +13,17 @@
#include "slang/ast/symbols/MemberSymbols.h"
#include "slang/diagnostics/DeclarationsDiags.h"
#include "slang/syntax/AllSyntax.h"
#include "slang/syntax/SyntaxTree.h"

namespace slang::ast {

using namespace parsing;
using namespace syntax;

CompilationUnitSymbol::CompilationUnitSymbol(Compilation& compilation) :
Symbol(SymbolKind::CompilationUnit, "", SourceLocation()), Scope(compilation, this) {
CompilationUnitSymbol::CompilationUnitSymbol(Compilation& compilation,
const SourceLibrary* sourceLibrary) :
Symbol(SymbolKind::CompilationUnit, "", SourceLocation()),
Scope(compilation, this), sourceLibrary(sourceLibrary) {

// Default the time scale to the compilation default. If it turns out
// this scope has a time unit declaration it will overwrite the member.
Expand Down Expand Up @@ -234,11 +237,10 @@ DefinitionSymbol::DefinitionSymbol(const Scope& scope, LookupLocation lookupLoca
const ModuleDeclarationSyntax& syntax,
const NetType& defaultNetType, UnconnectedDrive unconnectedDrive,
std::optional<TimeScale> directiveTimeScale,
const SyntaxTree* syntaxTree,
const SourceLibrary* sourceLibrary) :
const SyntaxTree* syntaxTree) :
Symbol(SymbolKind::Definition, syntax.header->name.valueText(), syntax.header->name.location()),
defaultNetType(defaultNetType), unconnectedDrive(unconnectedDrive), syntaxTree(syntaxTree),
sourceLibrary(sourceLibrary) {
sourceLibrary(syntaxTree ? syntaxTree->getSourceLibrary() : nullptr) {

// Extract and save various properties of the definition.
setParent(scope, lookupLocation.getIndex());
Expand Down Expand Up @@ -332,11 +334,9 @@ void DefinitionSymbol::serializeTo(ASTSerializer&) const {
}

ConfigBlockSymbol& ConfigBlockSymbol::fromSyntax(const Scope& scope,
const ConfigDeclarationSyntax& syntax,
const SourceLibrary* sourceLibrary) {
const ConfigDeclarationSyntax& syntax) {
auto& comp = scope.getCompilation();
auto result = comp.allocConfigBlock(syntax.name.valueText(), syntax.name.location(),
sourceLibrary);
auto result = comp.allocConfigBlock(syntax.name.valueText(), syntax.name.location());
result->setSyntax(syntax);
result->setAttributes(scope, syntax.attributes);

Expand Down
6 changes: 3 additions & 3 deletions source/ast/symbols/MemberSymbols.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -948,12 +948,12 @@ static void createTableEntries(const Scope& scope, const UdpEntrySyntax& syntax,
expandTableEntries(scope, syntax, fields, currEntry, 0, entry, results, rowDupMap);
}

PrimitiveSymbol& PrimitiveSymbol::fromSyntax(const Scope& scope, const UdpDeclarationSyntax& syntax,
const SourceLibrary* sourceLibrary) {
PrimitiveSymbol& PrimitiveSymbol::fromSyntax(const Scope& scope,
const UdpDeclarationSyntax& syntax) {
auto& comp = scope.getCompilation();
auto primName = syntax.name.valueText();
auto prim = comp.emplace<PrimitiveSymbol>(comp, primName, syntax.name.location(),
PrimitiveSymbol::UserDefined, sourceLibrary);
PrimitiveSymbol::UserDefined);
prim->setAttributes(scope, syntax.attributes);
prim->setSyntax(syntax);

Expand Down
Loading

0 comments on commit d33f06c

Please sign in to comment.