class
#include <slang/ast/Compilation.h>
Compilation A centralized location for creating and caching symbols.
This includes creating symbols from syntax nodes as well as fabricating them synthetically. Common symbols such as built in types are exposed here as well.
A Compilation object is the entry point for building ASTs. Typically you add one or more SyntaxTrees to the compilation and then call getRoot() to retrieve the root of the elaborated AST, and getAllDiagnostics() to get a list of all diagnostics issued in the design.
Base classes
- class slang::BumpAllocator
- BumpAllocator - Fast O(1) allocator.
Public types
- struct DefinitionLookupResult
- A struct containing the result of a definition lookup.
Constructors, destructors, conversion operators
- Compilation(const Bag& options = {}, const SourceLibrary* defaultLib = nullptr) explicit
- Constructs a new instance of the Compilation class.
Internal AST construction
-
void createDefinition(const Scope& scope,
LookupLocation location,
const syntax::
ModuleDeclarationSyntax& syntax) - Creates a new definition in the given scope based on the given syntax.
-
const PackageSymbol& createPackage(const Scope& scope,
const syntax::
ModuleDeclarationSyntax& syntax) - Creates a new package in the given scope based on the given syntax.
-
const ConfigBlockSymbol& createConfigBlock(const Scope& scope,
const syntax::
ConfigDeclarationSyntax& syntax) - Creates a new config block in the given scope based on the given syntax.
-
const PrimitiveSymbol& createPrimitive(Scope& scope,
const syntax::
UdpDeclarationSyntax& syntax) - Creates a new primitive in the given scope based on the given syntax.
- void addGateType(const PrimitiveSymbol& primitive)
- Registers a built-in gate symbol.
-
void setAttributes(const Symbol& symbol,
std::
span<const AttributeSymbol*const> attributes) - Sets the attributes associated with the given symbol.
-
void setAttributes(const Statement& stmt,
std::
span<const AttributeSymbol*const> attributes) - Sets the attributes associated with the given statement.
-
void setAttributes(const Expression& expr,
std::
span<const AttributeSymbol*const> attributes) - Sets the attributes associated with the given expression.
-
void setAttributes(const PortConnection& conn,
std::
span<const AttributeSymbol*const> attributes) - Sets the attributes associated with the given port connection.
-
void noteBindDirective(const syntax::
BindDirectiveSyntax& syntax, const Scope& scope) - Notes the presence of a bind directive.
- void noteInstanceWithDefBind(const Symbol& instance)
- Notes an instance that contains a bind directive targeting a global definition.
-
void noteDPIExportDirective(const syntax::
DPIExportSyntax& syntax, const Scope& scope) - Notes the presence of a DPI export directive.
-
void addOutOfBlockDecl(const Scope& scope,
const syntax::
ScopedNameSyntax& name, const syntax:: SyntaxNode& syntax, SymbolIndex index) - Tracks the existence of an out-of-block declaration (method or constraint) in the given scope.
-
std::
tuple<const syntax:: SyntaxNode*, SymbolIndex, bool*> findOutOfBlockDecl(const Scope& scope, std:: string_view className, std:: string_view declName) const - Searches for an out-of-block declaration in the given scope with declName for a className class.
- void addExternInterfaceMethod(const SubroutineSymbol& method)
- Tracks the existence of an extern interface method implementation.
- void noteDefaultClocking(const Scope& scope, const Symbol& clocking, SourceRange range)
- Notes that there is a default clocking block associated with the specified scope.
-
void noteDefaultClocking(const ASTContext& context,
const syntax::
DefaultClockingReferenceSyntax& syntax) - Notes that there is a default clocking block associated with the specified scope.
- const Symbol* getDefaultClocking(const Scope& scope) const
- Finds an applicable default clocking block for the given scope, or returns nullptr if no default clocking is in effect.
- void noteGlobalClocking(const Scope& scope, const Symbol& clocking, SourceRange range)
- Notes that there is a global clocking block associated with the specified scope.
- const Symbol* getGlobalClockingAndNoteUse(const Scope& scope)
- Finds an applicable global clocking block for the given scope, or returns nullptr if no global clocking is in effect.
- void noteDefaultDisable(const Scope& scope, const Expression& expr)
- Notes that there is a default disable associated with the specified scope.
- const Expression* getDefaultDisable(const Scope& scope) const
- Finds an applicable default disable expression for the given scope, or returns nullptr if no such declaration is in effect.
-
void noteExternDefinition(const Scope& scope,
const syntax::
SyntaxNode& syntax) - Notes the existence of an extern module/interface/program/primitive declaration.
-
const syntax::
SyntaxNode* getExternDefinition(std:: string_view name, const Scope& scope) const - Performs a lookup for an extern module/interface/program/primitive declaration of the given name.
-
void noteReference(const syntax::
SyntaxNode& node, bool isLValue = false) - Notes that the given syntax node is "referenced" somewhere in the AST.
- void noteReference(const Symbol& symbol, bool isLValue = false)
- Notes that the given symbol is "referenced" somewhere in the AST.
-
std::
pair<bool, bool> isReferenced(const syntax:: SyntaxNode& node) const - Checks whether the given syntax node has been referenced in the AST thus far.
- void noteNameConflict(const Symbol& symbol)
- Notes that the given symbol has a name conflict in its parent scope.
- void noteNetAlias(const Scope& scope, const Symbol& firstSym, AliasBitRange firstRange, const Expression& firstExpr, const Symbol& secondSym, AliasBitRange secondRange, const Expression& secondExpr)
- Makes note of an alias defined between the bit ranges of the two given symbols.
- void noteUpwardReference(const Scope& scope, const HierarchicalReference& ref)
- Notes the existence of the given upward hierarchical reference, which is used, among other things, to ensure we perform instance caching correctly.
- void noteHierarchicalAssignment(const HierarchicalReference& ref)
- Notes the existence of an assignment to a hierarchical reference.
- void noteVirtualIfaceInstance(const InstanceSymbol& instance)
- Notes the existence of a virtual interface type declaration for the given instance.
- void addDiagnostics(const Diagnostics& diagnostics)
- Adds a set of diagnostics to the compilation's list of semantic diagnostics.
- void forceElaborate(const Symbol& symbol)
- Forces the given symbol and all scopes underneath it to be elaborated and any relevant diagnostics to be issued.
-
std::
optional<TimeScale> getDefaultTimeScale() const - Gets the default time scale to use when none is specified in the source code.
- int getNextEnumSystemId()
- Gets the next system ID to use for identifying enum types.
- int getNextStructSystemId()
- Gets the next system ID to use for identifying struct types.
- int getNextUnionSystemId()
- Gets the next system ID to use for identifying union types.
Top-level API
- const CompilationOptions& getOptions() const
- Gets the set of options used to construct the compilation.
- bool hasFlag(bitmask<CompilationFlags> flags) const
- Returns true if the given flag(s) are enabled for this compilation.
- LanguageVersion languageVersion() const
- Gets the language version set in the compilation options.
- const SourceManager* getSourceManager() const
- Gets the source manager associated with the compilation.
-
void addSyntaxTree(std::
shared_ptr<syntax:: SyntaxTree> tree) - Adds a syntax tree to the compilation.
-
std::
span<const std:: shared_ptr<syntax:: SyntaxTree>> getSyntaxTrees() const - Gets the set of syntax trees that have been added to the compilation.
- const RootSymbol& getRoot()
- Gets the root of the design.
- const RootSymbol& getRootNoFinalize() const
- Gets the root of the design without attempting to finalize it.
- bool isFinalized() const
- Indicates whether the design has been compiled and can no longer accept modifications.
- bool isElaborated() const
- Indicates whether the design has been elaborated such that the AST is fully resolved and all symbols have been created.
- const Diagnostics& getParseDiagnostics()
- Gets the diagnostics produced during lexing, preprocessing, and syntax parsing.
- const Diagnostics& getSemanticDiagnostics()
- Gets the diagnostics produced during semantic analysis, including the creation of symbols, type checking, and name lookup.
- const Diagnostics& getAllDiagnostics()
- Gets all of the diagnostics produced during compilation.
- bool hasIssuedErrors() const
- Queries if any errors have been issued on any scope within this compilation.
- bool hasFatalErrors() const
- Returns true if there are any fatal errors reported in the compilation, or if we've hit the configured error limit and stopped elaboration early because of it.
Utility and convenience methods
-
const syntax::
NameSyntax& parseName(std:: string_view name) - A convenience method for parsing a name string and turning it into a set of syntax nodes.
-
const syntax::
NameSyntax& tryParseName(std:: string_view name, Diagnostics& diags) - A convenience method for parsing a name string and turning it into a set of syntax nodes.
- CompilationUnitSymbol& createScriptScope()
- Creates a new compilation unit within the design that can be modified dynamically, which is useful in runtime scripting scenarios.
Lookup and query methods
-
const CompilationUnitSymbol* getCompilationUnit(const syntax::
CompilationUnitSyntax& syntax) const - Gets the compilation unit for the given syntax node.
-
std::
span<const CompilationUnitSymbol*const> getCompilationUnits() const - Gets the set of compilation units that have been added to the compilation.
-
const SourceLibrary* getSourceLibrary(std::
string_view name) const - Gets the source library with the given name, or nullptr if there is no such library.
- const SourceLibrary& getDefaultLibrary() const
- Gets the default library object.
-
DefinitionLookupResult tryGetDefinition(std::
string_view name, const Scope& scope) const - Gets the definition with the given name, or nullptr if there is no such definition.
-
DefinitionLookupResult getDefinition(std::
string_view name, const Scope& scope, SourceRange sourceRange, DiagCode code) const - Gets the definition with the given name, or nullptr if there is no such definition.
-
DefinitionLookupResult getDefinition(std::
string_view name, const Scope& scope, const ConfigRule& configRule, SourceRange sourceRange, DiagCode code) const - Gets the definition indicated by the given config rule, or nullptr if it does not exist.
-
DefinitionLookupResult getDefinition(std::
string_view name, const Scope& scope, SourceRange sourceRange, const BindDirectiveInfo& bindInfo) const - Gets the definition indicated by the given bind directive info.
-
const DefinitionSymbol* getDefinition(const Scope& scope,
const syntax::
ModuleDeclarationSyntax& syntax) const - Gets the definition for the given syntax node, or nullptr if it does not exist.
-
const DefinitionSymbol* getDefinition(const ConfigBlockSymbol& config,
std::
string_view cellName, std:: string_view libName, SourceRange sourceRange) const - Gets the definition indicated by the given config and cell ID, or nullptr if it does not exist.
-
std::
vector<const Symbol*> getDefinitions() const - Gets a list of all definitions (including primitives) in the design.
-
std::
span<const DefinitionSymbol*const> getUnreferencedDefinitions() const - Gets a list of definitions that are unreferenced in the design.
-
const PackageSymbol* getPackage(std::
string_view name) const - Gets the package with the give name, or nullptr if there is no such package.
- const PackageSymbol& getStdPackage() const
- Gets the built-in 'std' package.
-
std::
vector<const PackageSymbol*> getPackages() const - Gets a list of all packages in the design.
-
const PrimitiveSymbol* getGateType(std::
string_view name) const - Gets the built-in gate type with the given name, or nullptr if there is no such gate.
System function management
-
void addSystemSubroutine(const std::
shared_ptr<SystemSubroutine>& subroutine) - Registers a system subroutine handler, which can be accessed by compiled code.
-
void addSystemMethod(SymbolKind typeKind,
const std::
shared_ptr<SystemSubroutine>& method) - Registers a type-based system method handler, which can be accessed by compiled code.
-
const SystemSubroutine* getSystemSubroutine(std::
string_view name) const - Gets a system subroutine with the given name, or nullptr if there is no such subroutine registered.
- const SystemSubroutine* getSystemSubroutine(parsing::KnownSystemName knownNameId) const
- Gets a system subroutine with the given KnownSystemName, or nullptr if there is no such subroutine registered.
-
const SystemSubroutine* getSystemMethod(SymbolKind typeKind,
std::
string_view name) const - Gets a system method for the specified type with the given name, or nullptr if there is no such method registered.
-
std::
span<const AttributeSymbol*const> getAttributes(const Symbol& symbol) const - Gets the attributes associated with the given symbol.
-
std::
span<const AttributeSymbol*const> getAttributes(const Statement& stmt) const - Gets the attributes associated with the given statement.
-
std::
span<const AttributeSymbol*const> getAttributes(const Expression& expr) const - Gets the attributes associated with the given expression.
-
std::
span<const AttributeSymbol*const> getAttributes(const PortConnection& conn) const - Gets the attributes associated with the given port connection.
Types
- const Type& getType(syntax::SyntaxKind kind) const
- Gets the type associated with the given syntax node kind.
-
const Type& getType(const syntax::
DataTypeSyntax& node, const ASTContext& context, const Type* typedefTarget = nullptr) - Gets the type represented by the given data type syntax node.
-
const Type& getType(const Type& elementType,
const syntax::
SyntaxList<syntax:: VariableDimensionSyntax>& dimensions, const ASTContext& context) - Gets an array type created from the given element type and dimensions.
-
const Type& getType(bitwidth_
t width, bitmask<IntegralFlags> flags) - Gets an integral vector type with the given size and flags.
- const Type& getScalarType(bitmask<IntegralFlags> flags) const
- Gets a scalar (single bit) type with the given flags.
- const NetType& getNetType(parsing::TokenKind kind) const
- Gets the nettype represented by the given token kind.
- const Type& getBitType() const
- Get the built-in
bit
type. - const Type& getLogicType() const
- Get the built-in
logic
type. - const Type& getIntType() const
- Get the built-in
int
type. - const Type& getByteType() const
- Get the built-in
byte
type. - const Type& getIntegerType() const
- Get the built-in
integer
type. - const Type& getRealType() const
- Get the built-in
real
type. - const Type& getShortRealType() const
- Get the built-in
shortreal
type. - const Type& getStringType() const
- Get the built-in
string
type. - const Type& getVoidType() const
- Get the built-in
void
type. - const Type& getErrorType() const
- Get the error type, which is used as a placeholder to represent an invalid type.
- const Type& getUnsignedIntType()
- Get the built-in
int unsigned
type. - const Type& getNullType() const
- Get the built-in
null
type. - const Type& getUnboundedType() const
- Get the built-in
$
type. - const Type& getTypeRefType() const
- Get the built-in type used for the result of the
type()
operator. - const NetType& getWireNetType() const
- Get the
wire
built in net type.
Allocation functions
- ConstantValue* allocConstant(ConstantValue&& value)
- Allocates space for a constant value in the pool of constants.
- SymbolMap* allocSymbolMap()
- Allocates a symbol map.
- PointerMap* allocPointerMap()
- Allocates a pointer map.
- AssertionInstanceDetails* allocAssertionDetails()
- Allocates an assertion instance details object.
-
template<typename... Args>GenericClassDefSymbol* allocGenericClass(Args && ... args)
- Allocates a generic class symbol.
-
ConfigBlockSymbol* allocConfigBlock(std::
string_view name, SourceLocation loc) - Allocates a config block symbol.
-
Scope::
WildcardImportData* allocWildcardImportData() - Allocates a scope's wildcard import data object.
-
const syntax::
ImplicitTypeSyntax& createEmptyTypeSyntax(SourceLocation loc) - Creates an empty ImplicitTypeSyntax object.
Function documentation
void slang:: ast:: Compilation:: noteBindDirective(const syntax:: BindDirectiveSyntax& syntax,
const Scope& scope)
Notes the presence of a bind directive.
These can be later checked during scope elaboration to include the newly bound instances.
void slang:: ast:: Compilation:: noteInstanceWithDefBind(const Symbol& instance)
Notes an instance that contains a bind directive targeting a global definition.
These are later checked for correctness.
void slang:: ast:: Compilation:: noteDPIExportDirective(const syntax:: DPIExportSyntax& syntax,
const Scope& scope)
Notes the presence of a DPI export directive.
These will be checked for correctness but are otherwise unused by SystemVerilog code.
void slang:: ast:: Compilation:: addOutOfBlockDecl(const Scope& scope,
const syntax:: ScopedNameSyntax& name,
const syntax:: SyntaxNode& syntax,
SymbolIndex index)
Tracks the existence of an out-of-block declaration (method or constraint) in the given scope.
This can later be retrieved by calling findOutOfBlockDecl().
std:: tuple<const syntax:: SyntaxNode*, SymbolIndex, bool*> slang:: ast:: Compilation:: findOutOfBlockDecl(const Scope& scope,
std:: string_view className,
std:: string_view declName) const
Searches for an out-of-block declaration in the given scope with declName for a className class.
Returns a tuple of syntax pointer and symbol index in the defining scope, along with a pointer that should be set to true if the resulting decl is considered "used". If not found, the syntax pointer will be null.
void slang:: ast:: Compilation:: addExternInterfaceMethod(const SubroutineSymbol& method)
Tracks the existence of an extern interface method implementation.
These are later elaborated by the compilation to hook up connections to their interface prototypes.
const Symbol* slang:: ast:: Compilation:: getGlobalClockingAndNoteUse(const Scope& scope)
Finds an applicable global clocking block for the given scope, or returns nullptr if no global clocking is in effect.
The use of the global clocking will be noted as a side effect of the instance containing the given scope.
void slang:: ast:: Compilation:: noteReference(const syntax:: SyntaxNode& node,
bool isLValue = false)
Notes that the given syntax node is "referenced" somewhere in the AST.
This is used to diagnose unused variables, nets, etc. The isLValue parameter is used to tell whether a value is only assigned or whether it's also read somewhere.
void slang:: ast:: Compilation:: noteReference(const Symbol& symbol,
bool isLValue = false)
Notes that the given symbol is "referenced" somewhere in the AST.
This is used to diagnose unused variables, nets, etc. The isLValue parameter is used to tell whether a value is only assigned or whether it's also read somewhere.
std:: pair<bool, bool> slang:: ast:: Compilation:: isReferenced(const syntax:: SyntaxNode& node) const
Checks whether the given syntax node has been referenced in the AST thus far.
The result is a pair, the first item of which is true if the node has been used as a non-lvalue, and the second of which is true if the node has been used as an lvalue. The second item is only relevant for nodes where it makes sense; e.g. variables and nets.
void slang:: ast:: Compilation:: noteNameConflict(const Symbol& symbol)
Notes that the given symbol has a name conflict in its parent scope.
This will cause appropriate errors to be issued.
void slang:: ast:: Compilation:: noteNetAlias(const Scope& scope,
const Symbol& firstSym,
AliasBitRange firstRange,
const Expression& firstExpr,
const Symbol& secondSym,
AliasBitRange secondRange,
const Expression& secondExpr)
Makes note of an alias defined between the bit ranges of the two given symbols.
This is used to check for duplicate aliases between the bit ranges.
const SourceManager* slang:: ast:: Compilation:: getSourceManager() const
Gets the source manager associated with the compilation.
If no syntax trees have been added to the design this method will return nullptr.
void slang:: ast:: Compilation:: addSyntaxTree(std:: shared_ptr<syntax:: SyntaxTree> tree)
Adds a syntax tree to the compilation.
If the compilation has already been finalized by calling getRoot this call will throw an exception.
const RootSymbol& slang:: ast:: Compilation:: getRoot()
Gets the root of the design.
The first time you call this method all top-level instances will be elaborated and the compilation finalized. After that you can no longer make any modifications to the compilation object; any attempts to do so will result in an exception.
const RootSymbol& slang:: ast:: Compilation:: getRootNoFinalize() const
Gets the root of the design without attempting to finalize it.
This means that (if the design has not been finalized previously) things like defparams will not be resolved, root instances will not have been created, etc.
bool slang:: ast:: Compilation:: isElaborated() const
Indicates whether the design has been elaborated such that the AST is fully resolved and all symbols have been created.
This is distinct from being finalized, which only means that the design has been parsed and syntax trees have been added.
This is only set once getAllDiagnostics() is called, after which point the compilation is functionally immutable.
const Diagnostics& slang:: ast:: Compilation:: getSemanticDiagnostics()
Gets the diagnostics produced during semantic analysis, including the creation of symbols, type checking, and name lookup.
Note that this will finalize the compilation, including forcing the evaluation of any symbols or expressions that were still waiting for lazy evaluation.
const syntax:: NameSyntax& slang:: ast:: Compilation:: parseName(std:: string_view name)
A convenience method for parsing a name string and turning it into a set of syntax nodes.
This is mostly for testing and API purposes; normal compilation never does this. Throws an exception if there are errors parsing the name.
const syntax:: NameSyntax& slang:: ast:: Compilation:: tryParseName(std:: string_view name,
Diagnostics& diags)
A convenience method for parsing a name string and turning it into a set of syntax nodes.
This is mostly for testing and API purposes. Errors are added to the provided diagnostics bag.
CompilationUnitSymbol& slang:: ast:: Compilation:: createScriptScope()
Creates a new compilation unit within the design that can be modified dynamically, which is useful in runtime scripting scenarios.
Note that this call will succeed even if the design has been finalized, but in that case any instantiations in the script scope won't affect which modules are determined to be top-level instances.
const CompilationUnitSymbol* slang:: ast:: Compilation:: getCompilationUnit(const syntax:: CompilationUnitSyntax& syntax) const
Gets the compilation unit for the given syntax node.
The compilation unit must have already been added to the compilation previously via a call to addSyntaxTree – otherwise returns nullptr.
DefinitionLookupResult slang:: ast:: Compilation:: tryGetDefinition(std:: string_view name,
const Scope& scope) const
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 before more global ones.
DefinitionLookupResult slang:: ast:: Compilation:: getDefinition(std:: string_view name,
const Scope& scope,
SourceRange sourceRange,
DiagCode code) const
Gets the definition with the given name, or nullptr if there is no such definition.
If no definition is found an appropriate diagnostic will be issued.
DefinitionLookupResult slang:: ast:: Compilation:: getDefinition(std:: string_view name,
const Scope& scope,
const ConfigRule& configRule,
SourceRange sourceRange,
DiagCode code) const
Gets the definition indicated by the given config rule, or nullptr if it does not exist.
If no definition is found an appropriate diagnostic will be issued.
const DefinitionSymbol* slang:: ast:: Compilation:: getDefinition(const ConfigBlockSymbol& config,
std:: string_view cellName,
std:: string_view libName,
SourceRange sourceRange) const
Gets the definition indicated by the given config and cell ID, or nullptr if it does not exist.
If no definition is found an appropriate diagnostic will be issued.
const NetType& slang:: ast:: Compilation:: getNetType(parsing::TokenKind kind) const
Gets the nettype represented by the given token kind.
If the token kind does not represent a nettype this will return the error nettype.
const NetType& slang:: ast:: Compilation:: getWireNetType() const
Get the wire
built in net type.
The rest of the built-in net types are rare enough that we don't bother providing dedicated accessors for them.