public void DefineStruct(IReadOnlyList <Tuple <String, ExprType> > attribs) { if (this.IsComplete) { throw new InvalidOperationException("Cannot redefine a struct."); } this._attribs = new List <Utils.StoreEntry>(); Int32 offset = 0; Int32 struct_alignment = 0; foreach (Tuple <String, ExprType> attrib in attribs) { String name = attrib.Item1; ExprType type = attrib.Item2; Int32 attrib_alignment = type.Alignment; // All attributes must be aligned. // This means that the alignment of the struct is the largest attribute alignment. struct_alignment = Math.Max(struct_alignment, attrib_alignment); // Make sure all attributes are put into aligned places. offset = Utils.RoundUp(offset, attrib_alignment); this._attribs.Add(new Utils.StoreEntry(name, type, offset)); offset += type.SizeOf; } this._size_of = Utils.RoundUp(offset, struct_alignment); }
// PushEntry // ========= // input: loc, name, Type // output: Scope // returns a new scope with everything the same as this, excpet for a new entry // public Scope PushEntry(EntryKind loc, String name, ExprType type) { Scope scope = new Scope(this); switch (loc) { case EntryKind.STACK: scope.esp_pos -= Utils.RoundUp(type.SizeOf, 4); scope.locals.Add(new Utils.StoreEntry(name, type, scope.esp_pos)); break; case EntryKind.GLOBAL: scope.globals.Add(new Utils.StoreEntry(name, type, 0)); break; case EntryKind.TYPEDEF: scope.typedefs.Add(new Utils.StoreEntry(name, type, 0)); break; default: return(null); } return(scope); }