![]() |
Spicy
|
#include <ast-context.h>
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::UID > | parseSource (Builder *builder, const hilti::rt::filesystem::path &path, std::optional< hilti::rt::filesystem::path > process_extension={}) |
| Result< declaration::module::UID > | 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) |
| declaration::Module * | newModule (Builder *builder, ID id, const hilti::rt::filesystem::path &process_extension) |
| declaration::Module * | module (const declaration::module::UID &uid) const |
| Result< Nothing > | processAST (Builder *builder, Driver *driver) |
| Driver * | driver () const |
| std::set< declaration::module::UID > | dependencies (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) |
| Declaration * | lookup (ast::DeclarationIndex index) |
| void | replace (Declaration *old, Declaration *new_) |
| ast::TypeIndex | register_ (UnqualifiedType *type) |
| UnqualifiedType * | lookup (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 () |
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.
| ASTContext::ASTContext | ( | Context * | context | ) |
Constructor.
| context | compiler context to use for logging and error reporting |
| ASTContext::~ASTContext | ( | ) |
Destructor.
| void ASTContext::clear | ( | ) |
Release all state.
|
inline |
Returns the current compiler context in use.
| 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().
| uid | UID of module to return dependencies for; the module must be known, otherwise an internal error is reported |
| recursive | if true, return the transitive closure of all dependent units, vs just direct dependencies of the specified unit |
| 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.
| d | declaration to return dependencies for, which must be part of the AST and declared at the root or module level |
|
inline |
During AST processing, returns the current compiler driver. If called outside of `processAST() executing, it will return null.
| void ASTContext::dump | ( | const hilti::logging::DebugStream & | stream, |
| const std::string & | prefix | ||
| ) |
Dumps the current total AST of all modules to a debug stream.
| stream | debug stream to write to |
| prefix | prefix line to start output with |
| void ASTContext::garbageCollect | ( | ) |
Clears up an AST nodes that are not currently retained by anybody.
| 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.
| builder | builder to use for constructing the parsed AST |
| id | name of the module to import (as in: import <id>) |
| scope | search scope for the import (as in: import ... from <scope>) |
| parse_extension | file extension indicating which plugin to use for parsing the module's source code |
| process_extension | if 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_dirs | list of directories to search for the module's source (in addition to any globally configured search directories) |
| Declaration * ASTContext::lookup | ( | ast::DeclarationIndex | index | ) |
Returns the declaration associated with an index.
| index | index to lookup, which must have been registered before to not trigger an internal error; unless its None, in which case it returns null. |
| UnqualifiedType * ASTContext::lookup | ( | ast::TypeIndex | index | ) |
Returns the type associated with an index.
| index | index to lookup, which must have been registered before to not trigger an internal error; unless its None, in which case it returns null. |
|
inline |
Factory function creating a new node of type T. This allocates the new through the context-wide memory resource.
| args | arguments to pass to the constructor of T |
|
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.
| ctx | first argument to pass to the constructor of T; must be this |
| children | second argument to pass to the constructor of T |
| args | remaining arguments to pass to the constructor of T |
|
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.
| ctx | first argument to pass to the constructor of T; must be this |
| wildcard | second argument to pass to the constructor of T; must be this |
| children | third second argument to pass to the constructor of T |
| args | remaining arguments to pass to the constructor of T |
|
inline |
Retrieves a module node from the AST given its UID. Returns null if no such module exists.
| uid | UID of module to return |
| declaration::Module * ASTContext::newModule | ( | Builder * | builder, |
| ID | id, | ||
| const hilti::rt::filesystem::path & | process_extension | ||
| ) |
Adds a new, empty module to the AST.
| 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
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.
| builder | current compiler builder, which AST processing may access |
| driver | current compiler driver, which AST processing may access |
| 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.
| decl | declaration to register |
None (and hence be larger than zero). | 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.
| decl | declaration to register |
None (and hence be larger than zero). | 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.
| old | old declaration; if it has not been registered yet at all, the method returns without doing anything |
| new | new declaration to take the place of the old one |
| 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.
| old | old type; if it has not been registered yet at all, the method returns without doing any tying |
| new | new type to take the place of the old one |
|
inline |
Returns the AST's root node. This always exists.
| 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.
| old_uid | existing UID; it's an internal error if this doesn't exist |
| new_uid | new UID to replace old_uid |