Spicy
Public Types | Public Member Functions | List of all members
hilti::ASTContext Class Reference

#include <ast-context.h>

Inheritance diagram for hilti::ASTContext:

Public Types

using DeclarationSet = std::set< Declaration *, ast::detail::DeclarationPtrCmp >
 

Public Member Functions

 ASTContext (Context *context)
 
 ~ASTContext ()
 
auto * compilerContext () const
 
auto root () const
 
Result< declaration::module::UIDparseSource (Builder *builder, const hilti::rt::filesystem::path &path, std::optional< hilti::rt::filesystem::path > process_extension={})
 
Result< declaration::module::UIDimportModule (Builder *builder, const ID &id, const ID &scope, const hilti::rt::filesystem::path &parse_extension, const std::optional< hilti::rt::filesystem::path > &process_extension, std::vector< hilti::rt::filesystem::path > search_dirs)
 
declaration::ModulenewModule (Builder *builder, ID id, const hilti::rt::filesystem::path &process_extension)
 
declaration::Modulemodule (const declaration::module::UID &uid) const
 
Result< NothingprocessAST (Builder *builder, Driver *driver)
 
Driverdriver () const
 
std::set< declaration::module::UIDdependencies (const declaration::module::UID &uid, bool recursive=false) const
 
const DeclarationSet & dependentDeclarations (Declaration *n)
 
void updateModuleUID (const declaration::module::UID &old_uid, const declaration::module::UID &new_uid)
 
ast::DeclarationIndex register_ (Declaration *decl)
 
Declarationlookup (ast::DeclarationIndex index)
 
void replace (Declaration *old, Declaration *new_)
 
ast::TypeIndex register_ (UnqualifiedType *type)
 
UnqualifiedTypelookup (ast::TypeIndex index)
 
void replace (UnqualifiedType *old, UnqualifiedType *new_)
 
ID uniqueCanononicalID (const ID &id)
 
void dump (const hilti::logging::DebugStream &stream, const std::string &prefix)
 
template<typename T , typename... Args>
T * make (Args &&... args)
 
template<typename T , typename... Args>
T * make (ASTContext *ctx, std::initializer_list< Node * > children, Args &&... args)
 
template<typename T , typename... Args>
T * make (ASTContext *ctx, type::Wildcard &&wildcard, std::initializer_list< Node * > children, Args &&... args)
 
void garbageCollect ()
 
void clear ()
 

Detailed Description

Environment for AST-wide state. The context maintains the AST root node and owns all nodes added to it or, recursively, any of if children. Each node can be part of just one AST context. Over time, the context also builds up further state about the AST.

Constructor & Destructor Documentation

◆ ASTContext()

ASTContext::ASTContext ( Context context)

Constructor.

Parameters
contextcompiler context to use for logging and error reporting

◆ ~ASTContext()

ASTContext::~ASTContext ( )

Destructor.

Member Function Documentation

◆ clear()

void ASTContext::clear ( )

Release all state.

◆ compilerContext()

auto* hilti::ASTContext::compilerContext ( ) const
inline

Returns the current compiler context in use.

◆ dependencies()

std::set<declaration::module::UID> hilti::ASTContext::dependencies ( const declaration::module::UID uid,
bool  recursive = false 
) const

Returns direct & indirect dependencies that a module imports. This information will be available only once the AST has been processed successfully through processAST().

Parameters
uidUID of module to return dependencies for; the module must be known, otherwise an internal error is reported
recursiveif true, return the transitive closure of all dependent units, vs just direct dependencies of the specified unit
Returns
set of dependencies

◆ dependentDeclarations()

const ASTContext::DeclarationSet & ASTContext::dependentDeclarations ( Declaration n)

Returns direct & indirect, global dependencies of a given global declaration. A "global declaration" is any declaration declared at either the root or the module level (i.e., node depth <= 2). The result will likewise include only such global declarations.

This information will be available only once the AST has been processed successfully through processAST(). If called before that, the method will abort with an internal error.

Parameters
ddeclaration to return dependencies for, which must be part of the AST and declared at the root or module level
Returns
dependencies of d, which will all be root or module-level nodes as well; will include the declaration d itself iff there's a dependency cycle where any of the children depends in turn on the declaration itself; will return an empty set if the declaration has no dependencies, including if d is not actually a global declaration

◆ driver()

Driver* hilti::ASTContext::driver ( ) const
inline

During AST processing, returns the current compiler driver. If called outside of `processAST() executing, it will return null.

◆ dump()

void ASTContext::dump ( const hilti::logging::DebugStream stream,
const std::string &  prefix 
)

Dumps the current total AST of all modules to a debug stream.

Parameters
streamdebug stream to write to
prefixprefix line to start output with

◆ garbageCollect()

void ASTContext::garbageCollect ( )

Clears up an AST nodes that are not currently retained by anybody.

◆ importModule()

Result< declaration::module::UID > ASTContext::importModule ( Builder builder,
const ID id,
const ID scope,
const hilti::rt::filesystem::path &  parse_extension,
const std::optional< hilti::rt::filesystem::path > &  process_extension,
std::vector< hilti::rt::filesystem::path >  search_dirs 
)

Imports a module from an external source file and adds it to the AST as a new module. This implements HILTI's import statement. If a module for the requested import is already part of the AST, returns the existing module without any further AST changes.

Parameters
builderbuilder to use for constructing the parsed AST
idname of the module to import (as in: import <id>)
scopesearch scope for the import (as in: import ... from <scope>)
parse_extensionfile extension indicating which plugin to use for parsing the module's source code
process_extensionif given, file extension indicating which plugin to use later for processing the resulting AST; if not given, the same plugin will be used as for parsing
search_dirslist of directories to search for the module's source (in addition to any globally configured search directories)
Returns
UID of the parsed module (which is now a part of the AST), or an error if parsing failed

◆ lookup() [1/2]

Declaration * ASTContext::lookup ( ast::DeclarationIndex  index)

Returns the declaration associated with an index.

Parameters
indexindex to lookup, which must have been registered before to not trigger an internal error; unless its None, in which case it returns null.

◆ lookup() [2/2]

UnqualifiedType * ASTContext::lookup ( ast::TypeIndex  index)

Returns the type associated with an index.

Parameters
indexindex to lookup, which must have been registered before to not trigger an internal error; unless its None, in which case it returns null.

◆ make() [1/3]

template<typename T , typename... Args>
T* hilti::ASTContext::make ( Args &&...  args)
inline

Factory function creating a new node of type T. This allocates the new through the context-wide memory resource.

Parameters
argsarguments to pass to the constructor of T

◆ make() [2/3]

template<typename T , typename... Args>
T* hilti::ASTContext::make ( ASTContext ctx,
std::initializer_list< Node * >  children,
Args &&...  args 
)
inline

Factory function creating a new node of type T. This allocates the new through the context-wide memory resource.

We need this variant because std::initializer_list cannot be passed through the generic std::forward.

Parameters
ctxfirst argument to pass to the constructor of T; must be this
childrensecond argument to pass to the constructor of T
argsremaining arguments to pass to the constructor of T

◆ make() [3/3]

template<typename T , typename... Args>
T* hilti::ASTContext::make ( ASTContext ctx,
type::Wildcard &&  wildcard,
std::initializer_list< Node * >  children,
Args &&...  args 
)
inline

Factory function creating a new node of type T. This allocates the new through the context-wide memory resource.

We need this variant because std::initializer_list cannot be passed through the generic std::forward.

Parameters
ctxfirst argument to pass to the constructor of T; must be this
wildcardsecond argument to pass to the constructor of T; must be this
childrenthird second argument to pass to the constructor of T
argsremaining arguments to pass to the constructor of T

◆ module()

declaration::Module* hilti::ASTContext::module ( const declaration::module::UID uid) const
inline

Retrieves a module node from the AST given its UID. Returns null if no such module exists.

Parameters
uidUID of module to return

◆ newModule()

declaration::Module * ASTContext::newModule ( Builder builder,
ID  id,
const hilti::rt::filesystem::path &  process_extension 
)

Adds a new, empty module to the AST.

◆ parseSource()

Result< declaration::module::UID > ASTContext::parseSource ( Builder builder,
const hilti::rt::filesystem::path &  path,
std::optional< hilti::rt::filesystem::path >  process_extension = {} 
)
   Parses a source file and adds it to the AST as a new module. If a module
   for this file is already part of the AST, returns the existing module
   without any further AST changes.

*

   @param builder builder to use for constructing the parsed AST
   @param path path to source file to parse
   @param process_extension if given, file extension indicating which
   plugin to use later for processing the resulting AST for the module; if
   not given, the same plugin will be used as for parsing (which is
   determined by the path's extension)
   @return UID of the parsed module (which is now a part of the AST), or an
   error if parsing failed

◆ processAST()

Result< Nothing > ASTContext::processAST ( Builder builder,
Driver driver 
)

Processes the whole AST with all of the compiler's visitor passes. This is the top-level entry point for all resolving/validating/optimizing. If successful, the will be fully resolved and validated; and ready for code generation.

Parameters
buildercurrent compiler builder, which AST processing may access
drivercurrent compiler driver, which AST processing may access

◆ register_() [1/2]

ast::DeclarationIndex ASTContext::register_ ( Declaration decl)

Registers a declaration with the context, assigning it a unique index through which it can later be retrieved. That index is automatically stored with the declaration as its `declarationindex().

If the declaration is a type declaration, the method also sets the declared type's declarationIndex() accordingly, linked the type with its declaration.

If the same declaration had already been registered earlier, nothing is changed; the method then simply returns the prior index.

Parameters
decldeclaration to register
Returns
the index now associated with the declaration; it's value is guaranteed to not be None (and hence be larger than zero).

◆ register_() [2/2]

ast::TypeIndex ASTContext::register_ ( UnqualifiedType type)

Registers a type with the context, assigning it a unique index through which it can later be retrieved. That index is automatically stored with the type as its `typeIndex().

If the same type had already been registered earlier, nothing is changed; the method then simply returns the prior index.

Parameters
decldeclaration to register
Returns
the index now associated with the type; it's value is guaranteed to not be None (and hence be larger than zero).

◆ replace() [1/2]

void ASTContext::replace ( Declaration old,
Declaration new_ 
)

Replaces a previously registered declaration with a new one. This means that any lookup for the existing declaration's index will now return the new declaration instead. The new declaration's declarationIndex() will automatically be set to index; the old declaration's declarationIndex() will not be changed.

If the new declaration is a type declaration, the method also sets the declared type's declarationIndex() accordingly, linking the type with its declaration. The old declaraed type is not changed.

Parameters
oldold declaration; if it has not been registered yet at all, the method returns without doing anything
newnew declaration to take the place of the old one

◆ replace() [2/2]

void ASTContext::replace ( UnqualifiedType old,
UnqualifiedType new_ 
)

Replaces a previously registered type with a new one. This means that any lookup for the existing type's index will now return the new type instead. The new type's typeIndex() will automatically be set to index; the old type's typeIndex() will not be changed.

Parameters
oldold type; if it has not been registered yet at all, the method returns without doing any tying
newnew type to take the place of the old one

◆ root()

auto hilti::ASTContext::root ( ) const
inline

Returns the AST's root node. This always exists.

◆ uniqueCanononicalID()

ID hilti::ASTContext::uniqueCanononicalID ( const ID id)
inline

Given an ID that's supposed to become a declaration's canonical ID, ensure that ID is globally unique within the context, returning an appropriately modified version if necessary.

◆ updateModuleUID()

void ASTContext::updateModuleUID ( const declaration::module::UID old_uid,
const declaration::module::UID new_uid 
)

Updates an existing UID with new information.

The given, old UID must correspond to a module parsed or imported into the context. This method then changes the module associated with that old UID to be associated with the new UID instead, and updates any context state accordingly, so that the module can now be found through the new UID.

Parameters
old_uidexisting UID; it's an internal error if this doesn't exist
new_uidnew UID to replace old_uid

The documentation for this class was generated from the following files: