Gyoji Compiler
Loading...
Searching...
No Matches
Public Member Functions | List of all members
Gyoji::frontend::lowering::ScopeTracker Class Reference

Tracks variables declared in each scope along with abels and goto statements in a highly simplified intermediate representation. More...

#include <function-scope.hpp>

Public Member Functions

 ~ScopeTracker ()
 Move along, nothing to see here.
 
void scope_push (const Gyoji::context::SourceReference &_source_ref)
 
void scope_push_loop (const Gyoji::context::SourceReference &_source_ref, size_t _loop_break_blockid, size_t _loop_continue_blockid)
 
void scope_pop ()
 
void label_define (std::string label_name, const Gyoji::context::SourceReference &_source_ref)
 
bool add_variable (std::string variable_name, const Gyoji::mir::Type *mir_type, const Gyoji::context::SourceReference &source_ref)
 
bool check (std::vector< std::pair< const ScopeOperation *, std::vector< const ScopeOperation * > > > &goto_fixups) const
 
bool is_in_loop () const
 
const LocalVariable * get_variable (std::string variable_name) const
 
std::vector< std::stringget_variables_to_unwind_for_root () const
 
std::vector< std::stringget_variables_to_unwind_for_scope () const
 
std::vector< std::stringget_variables_to_unwind_for_label (std::string &label) const
 

Detailed Description

Tracks variables declared in each scope along with abels and goto statements in a highly simplified intermediate representation.

This class exists to represent a scope in a highly simplified way that is specificatlly designed to provide all of the information needed to resolve labels and goto statements and unwind scopes when a goto/branch would take control of the program directly from one scope to another. Some of these constructs violate the 'normal' scope rules about variable declaration, so this is done in order to first check that the jump is legal and then to provide the information to the FunctionDefinitionResolver about what variables would be leaving scope when a goto occurs. In addition, there is logic here to deal with the fact that a 'goto' may precede its corresponding 'label' definition so that the code can be emitted anyway.

This scope tracker is only to be used inside the lowering process as an intermediate calculation and should not be used outside of that context.

Constructor & Destructor Documentation

◆ ~ScopeTracker()

ScopeTracker::~ScopeTracker ( )

Move along, nothing to see here.

Move along, nothing to see here.

Member Function Documentation

◆ add_variable()

bool ScopeTracker::add_variable ( std::string  variable_name,
const Gyoji::mir::Type mir_type,
const Gyoji::context::SourceReference source_ref 
)

Defines a variable in the current scope.

◆ check()

bool ScopeTracker::check ( std::vector< std::pair< const ScopeOperation *, std::vector< const ScopeOperation * > > > &  goto_fixups) const

This method could definitely use a better name. It does a few things and it's important that they be done together even though they are only somewhat related.

The main thing the method does is evaluate the scope rules for 'goto' statements and make sure that the result of the 'goto' would not skip variable declarations or initializations at the target label.

As a side-effect of the calculations, it also determines which variables would go out of scope as a result of the 'goto' statement and thus which ones need to be un-declared and the destructors called.

The parameter given 'goto_fixups' is an 'out' parameter that fills the vector with all of the 'goto' statements along with the vector of variables that need to be un-declared before the Jump statment of the goto. The vector of variables is in the order in which they should be destructed, so order is important when processing the fixups to the MIR.

◆ get_variable()

const LocalVariable * ScopeTracker::get_variable ( std::string  variable_name) const

Searches the current scope upwards toward the parent and returns the type of variable declared if it is defined. If it is not defined, returns nullptr to indicate that it's not defined anywhere in the current or parent scopes.

◆ get_variables_to_unwind_for_label()

std::vector< std::string > Gyoji::frontend::lowering::ScopeTracker::get_variables_to_unwind_for_label ( std::string label) const

Returns the list of variables to unwind (in order) to get back to a common ancestor of the label.

◆ get_variables_to_unwind_for_root()

std::vector< std::string > ScopeTracker::get_variables_to_unwind_for_root ( ) const

Returns the list of variables to unwind (in order) to get back to the root (like for a return).

◆ get_variables_to_unwind_for_scope()

std::vector< std::string > ScopeTracker::get_variables_to_unwind_for_scope ( ) const

Returns the list of variables to unwind (in order) to get back to the root (like for a return).

◆ is_in_loop()

bool ScopeTracker::is_in_loop ( ) const

Returns true if this or any ancestor is a 'loop' that can be 'break' or 'continue' out of.

◆ label_define()

void ScopeTracker::label_define ( std::string  label_name,
const Gyoji::context::SourceReference _source_ref 
)

Adds a label to the current scope with the basic_block it knows about. If it was seen first in a 'goto', we pull it out of that list and put it into the scope where it belongs.

◆ scope_pop()

void ScopeTracker::scope_pop ( )

Pop out of current scope back to parent.

◆ scope_push()

void ScopeTracker::scope_push ( const Gyoji::context::SourceReference _source_ref)

Enter a new (un-named) scope.

◆ scope_push_loop()

void ScopeTracker::scope_push_loop ( const Gyoji::context::SourceReference _source_ref,
size_t  _loop_break_blockid,
size_t  _loop_continue_blockid 
)

Pushes a 'loop' scope which knows where we would jump to in case of 'break' or 'continue'.


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