Exemplo n.º 1
0
void ParseEnumDeclaration(TABLE *table)
{   
	SYM *sp;
    TYP     *tp;
    if( lastst == id) {
        if((sp = search(lastid,&tagtable)) == NULL) {
            sp = allocSYM();
            sp->tp = allocTYP();
            sp->tp->type = bt_enum;
            sp->tp->size = 2;
            sp->tp->lst.head = 0;
			sp->tp->btp = 0;
            sp->storage_class = sc_type;
            sp->name = litlate(lastid);
            sp->tp->sname = sp->name;
            NextToken();
            if( lastst != begin)
                    error(ERR_INCOMPLETE);
            else {
				insert(sp,&tagtable);
				NextToken();
				ParseEnumerationList(table);
            }
        }
        else
            NextToken();
        head = sp->tp;
    }
    else {
        tp = allocTYP();	// fix here
        tp->type = bt_enum;
		tp->size = 2;
        if( lastst != begin)
            error(ERR_INCOMPLETE);
        else {
            NextToken();
            ParseEnumerationList(table);
        }
    head = tp;
    }
}
Exemplo n.º 2
0
TYP *maketype(int bt, int siz)
{
	TYP *tp;
    tp = allocTYP();
    tp->val_flag = 0;
    tp->size = siz;
    tp->type = bt;
	tp->typeno = bt;
    tp->sname = 0;
    tp->lst.head = 0;
    return tp;
}
Exemplo n.º 3
0
TYP *maketype(int bt, int siz)
{
	TYP *tp;
    tp = allocTYP();
    tp->val_flag = 0;
    tp->size = siz;
    tp->type = bt;
	tp->typeno = bt;
    tp->sname = 0;
    tp->lst.head = 0;
	tp->isUnsigned = FALSE;
	tp->isVolatile = FALSE;
	tp->isConst = FALSE;
    return tp;
}
Exemplo n.º 4
0
SYM     *makeint(char *name)
{       SYM     *sp;
        TYP     *tp;
        sp = allocSYM();
        tp = allocTYP();
        tp->type = bt_long;
        tp->size = 8;
        tp->btp = 0;
		tp->lst.head = 0;
        tp->sname = 0;
        sp->name = name;
        sp->storage_class = sc_auto;
        sp->tp = tp;
		sp->IsPrototype = FALSE;
        insert(sp,&lsyms);
        return sp;
}
Exemplo n.º 5
0
void ParseEnumDeclaration(TABLE *table)
{   
	SYM *sp;
    TYP     *tp;
    if( lastst == id) {
        if((sp = search(lastid,&tagtable)) == NULL) {
            sp = allocSYM();
            sp->tp = TYP::Make(bt_enum,1);
            sp->storage_class = sc_type;
            sp->SetName(*(new std::string(lastid)));
            sp->tp->sname = new std::string(*sp->name);
            NextToken();
            if( lastst != begin)
                    error(ERR_INCOMPLETE);
            else {
				tagtable.insert(sp);
				NextToken();
				ParseEnumerationList(table);
            }
        }
        else
            NextToken();
        head = sp->tp;
    }
    else {
        tp = allocTYP();	// fix here
        tp->type = bt_enum;
		tp->size = 1;
        if( lastst != begin)
            error(ERR_INCOMPLETE);
        else {
            NextToken();
            ParseEnumerationList(table);
        }
    head = tp;
    }
}
Exemplo n.º 6
0
int ParseStructDeclaration(int ztype)
{
    SYM     *sp;
    TYP     *tp;
    int gblflag;
    int ret;
    int psd;
    ENODE nd;
    ENODE *pnd = &nd;

    psd = isStructDecl;
    isStructDecl = TRUE;
    ret = 0;
    bit_offset = 0;
    bit_next = 0;
    bit_width = -1;
    if(lastst == id) {
        if((sp = search(lastid,&tagtable)) == NULL) {
            // If we encounted an unknown struct in a parameter list, we want
            // it to go into the global memory pool, not a local one.
            if (parsingParameterList) {
                gblflag = global_flag;
                global_flag++;
                sp = allocSYM();
                sp->name = litlate(lastid);
                global_flag = gblflag;
            }
            else {
                sp = allocSYM();
                sp->name = litlate(lastid);
            }
            sp->tp = allocTYP();
            sp->tp->type = ztype;
            sp->tp->typeno = typeno++;
            sp->tp->lst.head = 0;
            sp->storage_class = sc_type;
            sp->tp->sname = sp->name;
            sp->tp->alignment = 0;
            NextToken();

            if (lastst == kw_align) {
                NextToken();
                sp->tp->alignment = GetIntegerExpression(&pnd);
            }

            // Could be a forward structure declaration like:
            // struct buf;
            if (lastst==semicolon) {
                ret = 1;
                insert(sp,&tagtable);
                NextToken();
            }
            // Defining a pointer to an unknown struct ?
            else if (lastst == star) {
                insert(sp,&tagtable);
            }
            else if(lastst != begin)
                error(ERR_INCOMPLETE);
            else    {
                insert(sp,&tagtable);
                NextToken();
                ParseStructMembers(sp->tp,ztype);
            }
        }
        else {
            NextToken();
            if (lastst==kw_align) {
                NextToken();
                sp->tp->alignment = GetIntegerExpression(&pnd);
            }
            if (lastst==begin) {
                NextToken();
                ParseStructMembers(sp->tp,ztype);
            }
        }
        head = sp->tp;
    }
    else {
        tp = allocTYP();
        tp->type = ztype;
        tp->sname = 0;
        tp->lst.head = 0;

        if (lastst==kw_align) {
            NextToken();
            tp->alignment = GetIntegerExpression(&pnd);
        }

        if( lastst != begin)
            error(ERR_INCOMPLETE);
        else {
            NextToken();
            ParseStructMembers(tp,ztype);
        }
        head = tp;
    }
    isStructDecl = psd;
    return ret;
}
Exemplo n.º 7
0
/*
 *      process ParseSpecifierarations of the form:
 *
 *              <type>  <ParseSpecifier>, <ParseSpecifier>...;
 *
 *      leaves the ParseSpecifierarations in the symbol table pointed to by
 *      table and returns the number of bytes declared. al is the
 *      allocation type to assign, ilc is the initial location
 *      counter. if al is sc_member then no initialization will
 *      be processed. ztype should be bt_struct for normal and in
 *      structure ParseSpecifierarations and sc_union for in union ParseSpecifierarations.
 */
int declare(TABLE *table,int al,int ilc,int ztype)
{ 
	SYM *sp, *sp1, *sp2;
    TYP *dhead;
	char stnm[200];

    static long old_nbytes;
    int nbytes;

	nbytes = 0;
    ParseSpecifier(table);
    dhead = head;
    for(;;) {
        declid = 0;
		bit_width = -1;
        ParseDeclarationPrefix(ztype==bt_union);
        if( declid != 0) {      /* otherwise just struct tag... */
            sp = allocSYM();
			sp->name = declid;
            sp->storage_class = al;
			if (bit_width > 0 && bit_offset > 0) {
				// share the storage word with the previously defined field
				nbytes = old_nbytes - ilc;
			}
			old_nbytes = ilc + nbytes;
			if (al != sc_member) {
//							sp->isTypedef = isTypedef;
				if (isTypedef)
					sp->storage_class = sc_typedef;
				isTypedef = FALSE;
			}
            while( (ilc + nbytes) % alignment(head)) {
                if( al != sc_member && al != sc_external && al != sc_auto) {
					dseg();
					GenerateByte(0);
                }
                ++nbytes;
            }
			if( al == sc_static) {
				sp->value.i = nextlabel++;
			}
			else if( ztype == bt_union)
                sp->value.i = ilc;
            else if( al != sc_auto )
                sp->value.i = ilc + nbytes;
            else
                sp->value.i = -(ilc + nbytes + head->size);

			if (bit_width == -1)
				sp->tp = head;
			else {
				sp->tp = allocTYP();
				*(sp->tp) = *head;
				sp->tp->type = bt_bitfield;
				sp->tp->size = head->size;//tp_int.size;
				sp->tp->bit_width = bit_width;
				sp->tp->bit_offset = bit_offset;
			}

            if( 
				(sp->tp->type == bt_func) && 
                    sp->storage_class == sc_global )
                    sp->storage_class = sc_external;
            if(ztype == bt_union)
                    nbytes = imax(nbytes,sp->tp->size);
            else if(al != sc_external)
                    nbytes += sp->tp->size;
            if( sp->tp->type == bt_ifunc && (sp1 = search(sp->name,table)) != 0 &&
                    sp1->tp->type == bt_func )
                    {
                    sp1->tp = sp->tp;
                    sp1->storage_class = sp->storage_class;
//                                sp1->value.i = sp->value.i;
					sp1->IsPrototype = sp->IsPrototype;
                    sp = sp1;
                    }
			else {
				sp2 = search(sp->name,table);
				if (sp2 == NULL)
					insert(sp,table);
				else {
					if (funcdecl==2)
						sp2->tp = sp->tp;
					//else if (!sp2->IsPrototype)
					//	insert(sp,table);
				}
			}
            if( sp->tp->type == bt_ifunc) { /* function body follows */
                ParseFunction(sp);
                return nbytes;
            }
            if( (al == sc_global || al == sc_static) &&
                    sp->tp->type != bt_func && sp->storage_class!=sc_typedef)
                    doinit(sp);
        }
		if (funcdecl==TRUE) {
			if (lastst==comma || lastst==semicolon)
				break;
			if (lastst==closepa)
				goto xit1;
		}
		else if (catchdecl==TRUE) {
			if (lastst==closepa)
				goto xit1;
		}
		else if (lastst == semicolon)
			break;

        needpunc(comma);
        if(declbegin(lastst) == 0)
                break;
        head = dhead;
    }
    NextToken();
xit1:
    return nbytes;
}
Exemplo n.º 8
0
void Compiler::AddStandardTypes()
{
  TYP *p, *pchar, *pint;

  p = TYP::Make(bt_long,8);
  stdint = *p;
  pint = p;
  
  p = TYP::Make(bt_long,8);
  p->isUnsigned = true;
  stduint = *p;
  
  p = TYP::Make(bt_long,8);
  stdlong = *p;
  
  p = TYP::Make(bt_long,8);
  p->isUnsigned = true;
  stdulong = *p;
  
  p = TYP::Make(bt_short,4);
  stdshort = *p;
  
  p = TYP::Make(bt_short,4);
  p->isUnsigned = true;
  stdushort = *p;
  
  p = TYP::Make(bt_char,2);
  stdchar = *p;
  pchar = p;
  
  p = TYP::Make(bt_char,2);
  p->isUnsigned = true;
  stduchar = *p;
  
  p = allocTYP();
  p->type = bt_byte;
  p->typeno = bt_byte;
  p->size = 1;
  p->size2 = 1;
  p->bit_width = -1;
  stdbyte = *p;
  
  p = allocTYP();
  p->type = bt_byte;
  p->typeno = bt_byte;
  p->size = 1;
  p->size2 = 1;
  p->isUnsigned = true;
  p->bit_width = -1;
  stdubyte = *p;
  
  p = allocTYP();
  p->type = bt_pointer;
  p->typeno = bt_pointer;
  p->val_flag = 1;
  p->size = 1;
  p->size2 = 1;
  p->btp = pchar->GetIndex();
  p->bit_width = -1;
  stdstring = *p;
  
  p = allocTYP();
  p->type = bt_double;
  p->typeno = bt_double;
  p->size = 8;
  p->size2 = 8;
  p->bit_width = -1;
  stddbl = *p;
  stddouble = *p;
  
  p = allocTYP();
  p->type = bt_float;
  p->typeno = bt_float;
  p->size = 4;
  p->size2 = 4;
  p->bit_width = -1;
  stdflt = *p;
  
  p = TYP::Make(bt_func,0);
  p->btp = pint->GetIndex();
  stdfunc = *p;

  p = allocTYP();
  p->type = bt_exception;
  p->typeno = bt_exception;
  p->size = 8;
  p->size2 = 8;
  p->isUnsigned = true;
  p->bit_width = -1;
  stdexception = *p;

  p = allocTYP();
  p->type = bt_long;
  p->typeno = bt_long;
  p->val_flag = 1;
  p->size = 8;
  p->size2 = 8;
  p->bit_width = -1;
  stdconst = *p;
  
}
Exemplo n.º 9
0
/*
 *      process declarations of the form:
 *
 *              <type>  <specifier>, <specifier>...;
 *
 *      leaves the declarations in the symbol table pointed to by
 *      table and returns the number of bytes declared. al is the
 *      allocation type to assign, ilc is the initial location
 *      counter. if al is sc_member then no initialization will
 *      be processed. ztype should be bt_struct for normal and in
 *      structure ParseSpecifierarations and sc_union for in union ParseSpecifierarations.
 */
int declare(TABLE *table,int al,int ilc,int ztype)
{ 
	SYM *sp, *sp1, *sp2;
    TYP *dhead, *tp1, *tp2;
	ENODE *ep1, *ep2;
	char stnm[200];
	int op;
	int fd;
	int fn_doneinit = 0;
	int bcnt;

    static long old_nbytes;
    int nbytes;

	nbytes = 0;
    if (ParseSpecifier(table))
		return nbytes;
    dhead = head;
    for(;;) {
        declid = (char *)NULL;
		bit_width = -1;
        ParseDeclarationPrefix(ztype==bt_union);
		// If a function declaration is taking place and just the type is
		// specified without a parameter name, assign an internal compiler
		// generated name.
		if (funcdecl>0 && funcdecl != 10 && declid==(char *)NULL) {
			sprintf(lastid, "_p%d", nparms);
			declid = litlate(lastid);
			names[nparms++] = declid;
			missingArgumentName = TRUE;
		}
        if( declid != NULL) {      /* otherwise just struct tag... */
            sp = allocSYM();
			sp->name = declid;
            sp->storage_class = al;
            sp->isConst = isConst;
			if (bit_width > 0 && bit_offset > 0) {
				// share the storage word with the previously defined field
				nbytes = old_nbytes - ilc;
			}
			old_nbytes = ilc + nbytes;
			if (al != sc_member) {
//							sp->isTypedef = isTypedef;
				if (isTypedef)
					sp->storage_class = sc_typedef;
				isTypedef = FALSE;
			}
			if ((ilc + nbytes) % roundAlignment(head)) {
				if (al==sc_thread)
					tseg();
				else
					dseg();
            }
            bcnt = 0;
            while( (ilc + nbytes) % roundAlignment(head)) {
                ++nbytes;
                bcnt++;
            }
            if( al != sc_member && al != sc_external && al != sc_auto) {
                if (bcnt > 0)
                    genstorage(bcnt);
            }

			// Set the struct member storage offset.
			if( al == sc_static || al==sc_thread) {
				sp->value.i = nextlabel++;
			}
			else if( ztype == bt_union)
                sp->value.i = ilc;
            else if( al != sc_auto )
                sp->value.i = ilc + nbytes;
			// Auto variables are referenced negative to the base pointer
			// Structs need to be aligned on the boundary of the largest
			// struct element. If a struct is all chars this will be 2.
			// If a struct contains a pointer this will be 8. It has to
			// be the worst case alignment.
			else {
                sp->value.i = -(ilc + nbytes + roundSize(head));
			}

			if (bit_width == -1)
				sp->tp = head;
			else {
				sp->tp = allocTYP();
				*(sp->tp) = *head;
				sp->tp->type = bt_bitfield;
				sp->tp->size = head->size;//tp_int.size;
				sp->tp->bit_width = bit_width;
				sp->tp->bit_offset = bit_offset;
			}
			if (isConst)
				sp->tp->isConst = TRUE;
            if((sp->tp->type == bt_func) && sp->storage_class == sc_global )
                sp->storage_class = sc_external;

			// Increase the storage allocation by the type size.
            if(ztype == bt_union)
                nbytes = imax(nbytes,roundSize(sp->tp));
			else if(al != sc_external) {
				// If a pointer to a function is defined in a struct.
				if (isStructDecl && (sp->tp->type==bt_func || sp->tp->type==bt_ifunc))
					nbytes += 8;
				else
					nbytes += roundSize(sp->tp);
			}
            
			if (sp->tp->type == bt_ifunc && (sp1 = search(sp->name,table)) != 0 && sp1->tp->type == bt_func )
            {
				sp1->tp = sp->tp;
				sp1->storage_class = sp->storage_class;
	            sp1->value.i = sp->value.i;
				sp1->IsPrototype = sp->IsPrototype;
				sp = sp1;
            }
			else {
				sp2 = search(sp->name,table);
				if (sp2 == NULL)
					insert(sp,table);
				else {
					if (funcdecl==2)
						sp2->tp = sp->tp;
					//else if (!sp2->IsPrototype)
					//	insert(sp,table);
				}
			}
			if (needParseFunction) {
				needParseFunction = FALSE;
				fn_doneinit = ParseFunction(sp);
				if (sp->tp->type != bt_pointer)
					return nbytes;
			}
   //         if(sp->tp->type == bt_ifunc) { /* function body follows */
   //             ParseFunction(sp);
   //             return nbytes;
   //         }
            if( (al == sc_global || al == sc_static || al==sc_thread) && !fn_doneinit &&
                    sp->tp->type != bt_func && sp->tp->type != bt_ifunc && sp->storage_class!=sc_typedef)
                    doinit(sp);
        }
		if (funcdecl>0) {
			if (lastst==comma || lastst==semicolon)
				break;
			if (lastst==closepa)
				goto xit1;
		}
		else if (catchdecl==TRUE) {
			if (lastst==closepa)
				goto xit1;
		}
		else if (lastst == semicolon)
			break;
		else if (lastst == assign) {
			tp1 = nameref(&ep1);
            op = en_assign;
//            NextToken();
            tp2 = asnop(&ep2);
            if( tp2 == 0 || !IsLValue(ep1) )
                  error(ERR_LVALUE);
            else    {
                    tp1 = forcefit(&ep1,tp1,&ep2,tp2);
                    ep1 = makenode(op,ep1,ep2);
                    }
			sp->initexp = ep1;
			if (lastst==semicolon)
				break;
		}

        needpunc(comma);
        if(declbegin(lastst) == 0)
                break;
        head = dhead;
    }
    NextToken();
xit1:
    return nbytes;
}
Exemplo n.º 10
0
int StructDeclaration::Parse(int ztype)
{
  SYM *sp;
  TYP *tp;
	int ret;
	int psd;
	ENODE nd;
	ENODE *pnd = &nd;

  sp = nullptr;
	psd = isStructDecl;
	isStructDecl++;
	ret = 0;
	bit_offset = 0;
	bit_next = 0;
	bit_width = -1;
  if(lastst == id) {
    if((sp = tagtable.Find(lastid,false)) == NULL) {
      sp = allocSYM();
  		sp->SetName(*(new std::string(lastid)));
      sp->tp = allocTYP();
      sp->tp->type = (e_bt)ztype;
		  sp->tp->typeno = typeno++;
      sp->tp->lst.Clear();
      sp->storage_class = sc_type;
      sp->tp->sname = new std::string(*sp->name);
      sp->tp->alignment = 0;
      NextToken();

			if (lastst == kw_align) {
        NextToken();
        sp->tp->alignment = GetIntegerExpression(&pnd);
      }

			// Could be a forward structure declaration like:
			// struct buf;
			if (lastst==semicolon) {
				ret = 1;
        tagtable.insert(sp);
        NextToken();
			}
			// Defining a pointer to an unknown struct ?
			else if (lastst == star) {
        tagtable.insert(sp);
			}
      else if(lastst != begin)
        error(ERR_INCOMPLETE);
      else {
        tagtable.insert(sp);
        NextToken();
        ParseMembers(sp, sp->tp,ztype);
      }
    }
    // Else it is a known structure
		else {
      NextToken();
      if (lastst==kw_align) {
        NextToken();
        sp->tp->alignment = GetIntegerExpression(&pnd);
      }
			if (lastst==begin) {
        NextToken();
        ParseMembers(sp,sp->tp,ztype);
			}
		}
    head = sp->tp;
  }
  // Else there was no tag identifier
  else {
    tp = allocTYP();
    tp->type = (e_bt)ztype;
	  tp->typeno = typeno++;
    tp->sname = new std::string("");

    if (lastst==kw_align) {
      NextToken();
      tp->alignment = GetIntegerExpression(&pnd);
    }

    if( lastst != begin)
      error(ERR_INCOMPLETE);
    else {
			NextToken();
			ParseMembers(sp,tp,ztype);
    }
    head = tp;
  }
	isStructDecl = psd;
	return ret;
}
Exemplo n.º 11
0
// Class declarations have the form:
//
//	class identifier [: base class]
//  {
//		class members
//	}
//
// We could also have a forward reference:
//
//	class identifier;
//
// Or a pointer to a class:
//
//	class *identifier;
//
int ClassDeclaration::Parse(int ztype)
{
    SYM *sp, *bcsp;
	int ret;
	int psd;
	ENODE nd;
	ENODE *pnd = &nd;
	char *idsave;
	int alignment;
  SYM *cls;

  cls = currentClass;
	dfs.puts("<ParseClassDeclaration>\n");
	alignment = 0;
	isTypedef = TRUE;
	NextToken();
	if (lastst != id) {
		error(ERR_SYNTAX);
		goto lxit;
	}
//	ws = allocSYM();
	idsave = my_strdup(lastid);
//	ws->name = idsave;
//	ws->storage_class = sc_typedef;
	// Passes lastid onto struct parsing

	psd = isStructDecl;
	isStructDecl++;
	ret = 0;
	bit_offset = 0;
	bit_next = 0;
	bit_width = -1;

  dfs.printf("---------------------------------");
  dfs.printf("Class decl:%s\n", lastid);
  dfs.printf("---------------------------------");
	if((sp = tagtable.Find(std::string(lastid),false)) == NULL) {
    sp = allocSYM();
    sp->SetName(*(new std::string(lastid)));
		sp->tp = nullptr;
    NextToken();
    dfs.printf("A");
		if (lastst == kw_align) {
      NextToken();
      alignment = GetIntegerExpression(&pnd);
    }
    else
      alignment = AL_STRUCT;

		// Could be a forward structure declaration like:
		// struct buf;
		if (lastst==semicolon) {
      dfs.printf("B");
			ret = 1;
			printf("classdecl insert1\r\n");
      tagtable.insert(sp);
      NextToken();
		}
		// Defining a pointer to an unknown struct ?
		else if (lastst == star) {
      dfs.printf("C");
			printf("classdecl insert2\r\n");
      tagtable.insert(sp);
		}
		else if (lastst==colon) {
      dfs.printf("D");
			NextToken();
			// Absorb and ignore public/private keywords
			if (lastst == kw_public || lastst==kw_private)
				NextToken();
			if (lastst != id) {
				error(ERR_SYNTAX);
				goto lxit;
			}
			bcsp = tagtable.Find(std::string(lastid),false);
			if (bcsp==nullptr) {
				error(ERR_UNDEFINED);
				goto lxit;
			}
      dfs.printf("E");
			// Copy the type chain of base class
			//sp->tp = TYP::Copy(bcsp->tp);
			// Start off at the size of the base.
			sp->tp = allocTYP();
			sp->tp->lst.SetBase(bcsp->GetIndex());
			dfs.printf("Set base class: %d\n", sp->tp->lst.base);
			sp->tp->size = bcsp->tp->size;
			sp->tp->type = (e_bt)ztype;
			sp->tp->typeno = typeno++;
      sp->tp->sname = new std::string(*sp->name);
      sp->tp->alignment = alignment;
	    sp->storage_class = sc_type;
			NextToken();
			if (lastst != begin) {
        error(ERR_INCOMPLETE);
				goto lxit;
			}
			/*
			sp->tp = allocTYP();
			sp->tp->typeno = typeno++;
      sp->tp->sname =  new std::string(*sp->name);
      sp->tp->alignment = alignment;
			sp->tp->type = (e_bt)ztype;
			sp->tp->lst.SetBase(bcsp->GetIndex());
	    sp->storage_class = sc_type;
	    */
      tagtable.insert(sp);
      NextToken();
      currentClass = sp;
      dfs.printf("f");
      ParseMembers(sp,ztype);
      dfs.printf("G");
		}
    else if(lastst != begin)
      error(ERR_INCOMPLETE);
    else {
			if (sp->tp == nullptr) {
				sp->tp = allocTYP();
			}
			sp->tp->size = 0;
			sp->tp->typeno = typeno++;
      sp->tp->sname = new std::string(*sp->name);
      sp->tp->alignment = alignment;
			sp->tp->type = (e_bt)ztype;
			sp->tp->lst.SetBase(0);
	    sp->storage_class = sc_type;
      tagtable.insert(sp);
      NextToken();
      currentClass = sp;
      ParseMembers(sp,ztype);
    }
  }
  // Else the class was found in the tag table.
	else {
    NextToken();
    if (lastst==kw_align) {
	    NextToken();
      sp->tp->alignment = GetIntegerExpression(&pnd);
    }
		if (lastst==begin) {
        NextToken();
        currentClass = sp;
        ParseMembers(sp,ztype);
		}
	}
  head = sp->tp;
	isStructDecl = psd;
lxit:
	isTypedef = TRUE;
	if (classname) delete classname;
	classname = new std::string(idsave);
	currentClass = cls;
	dfs.puts("</ParseClassDeclaration>\n");
	return ret;
}