when building the AST, we construct the AST items very superficially, plugging in only the identifying TAGS etc, rather than the types and offsets etc. As soon as the tree is built, we need to run a pass over it to insert 'scope' objects so that when we later look for identifiers, we can restrict the search to relevant scopes. Once the full tree is built, we then run a pass over the tree and build out the details of the declarations, so that when we get to the code generation stage, we have all the offsets, sizes etc in the declarations. Now we do a pass over the data, pushing down structures from the known types at the top of the tree, down to the leaves; we match the expected and known types as we return back up the tree, and signal any incompatibility errors - or perform implicit casts (usually widening/narrowing) to the pairs. At the top level, we know what to expect from 1) assignments; 2) procedure parameters. Not so sure about statements such as x->field = y->field - all we can check is that the types of the final assigned field are the same.