+ return sig;
+}
+
+
+StructSig *Parser::parse_struct_sig() {
+ size_t id = read_uint();
+
+ StructSigState *sig = lookup(structs, id);
+
+ if (!sig) {
+ /* parse the signature */
+ sig = new StructSigState;
+ sig->id = id;
+ sig->name = read_string();
+ sig->num_members = read_uint();
+ const char **member_names = new const char *[sig->num_members];
+ for (unsigned i = 0; i < sig->num_members; ++i) {
+ member_names[i] = read_string();
+ }
+ sig->member_names = member_names;
+ sig->offset = file->currentOffset();
+ structs[id] = sig;
+ } else if (file->currentOffset() < sig->offset) {
+ /* skip over the signature */
+ skip_string(); /* name */
+ unsigned num_members = read_uint();
+ for (unsigned i = 0; i < num_members; ++i) {
+ skip_string(); /* member_name */
+ }
+ }
+
+ assert(sig);
+ return sig;
+}
+
+
+EnumSig *Parser::parse_enum_sig() {
+ size_t id = read_uint();
+
+ EnumSigState *sig = lookup(enums, id);
+
+ if (!sig) {
+ /* parse the signature */
+ sig = new EnumSigState;
+ sig->id = id;
+ sig->name = read_string();
+ Value *value = parse_value();
+ sig->value = value->toSInt();
+ delete value;
+ sig->offset = file->currentOffset();
+ enums[id] = sig;
+ } else if (file->currentOffset() < sig->offset) {
+ /* skip over the signature */
+ skip_string(); /*name*/
+ scan_value();
+ }
+
+ assert(sig);
+ return sig;
+}
+
+
+BitmaskSig *Parser::parse_bitmask_sig() {
+ size_t id = read_uint();
+
+ BitmaskSigState *sig = lookup(bitmasks, id);
+
+ if (!sig) {
+ /* parse the signature */
+ sig = new BitmaskSigState;
+ sig->id = id;
+ sig->num_flags = read_uint();
+ BitmaskFlag *flags = new BitmaskFlag[sig->num_flags];
+ for (BitmaskFlag *it = flags; it != flags + sig->num_flags; ++it) {
+ it->name = read_string();
+ it->value = read_uint();
+ if (it->value == 0 && it != flags) {
+ std::cerr << "warning: bitmask " << it->name << " is zero but is not first flag\n";
+ }
+ }
+ sig->flags = flags;
+ sig->offset = file->currentOffset();
+ bitmasks[id] = sig;
+ } else if (file->currentOffset() < sig->offset) {
+ /* skip over the signature */
+ int num_flags = read_uint();
+ for (int i = 0; i < num_flags; ++i) {
+ skip_string(); /*name */
+ skip_uint(); /* value */
+ }
+ }
+
+ assert(sig);
+ return sig;
+}
+
+
+void Parser::parse_enter(Mode mode) {
+ FunctionSig *sig = parse_function_sig();