OpenCores
URL https://opencores.org/ocsvn/thor/thor/trunk

Subversion Repositories thor

[/] [thor/] [trunk/] [FT64v5/] [software/] [CC64/] [source/] [ParseDeclarations.cpp] - Rev 48

Compare with Previous | Blame | View Log

// ============================================================================
//        __
//   \\__/ o\    (C) 2012-2018  Robert Finch, Waterloo
//    \  __ /    All rights reserved.
//     \/_//     robfinch<remove>@finitron.ca
//       ||
//
// CC64 - 'C' derived language compiler
//  - 64 bit CPU
//
// This source file is free software: you can redistribute it and/or modify 
// it under the terms of the GNU Lesser General Public License as published 
// by the Free Software Foundation, either version 3 of the License, or     
// (at your option) any later version.                                      
//                                                                          
// This source file is distributed in the hope that it will be useful,      
// but WITHOUT ANY WARRANTY; without even the implied warranty of           
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the            
// GNU General Public License for more details.                             
//                                                                          
// You should have received a copy of the GNU General Public License        
// along with this program.  If not, see <http://www.gnu.org/licenses/>.    
//                                                                          
// ============================================================================
//
#include "stdafx.h"
 
TYP *head = (TYP *)NULL;
TYP *tail = (TYP *)NULL;
std::string *declid;
//char *Declaration::declid = (char *)NULL;
TABLE tagtable;
TYP stdconst;
TYP stdvector;
TYP *stdvectormask;
Stringx names[20];
int nparms = 0;
int funcdecl = 0;		//0,1, or 2
int nfc = 0;
int isFirstCall = 0;
int catchdecl = FALSE;
int isTypedef = FALSE;
bool isUnion = false;
int isUnsigned = FALSE;
int isSigned = FALSE;
int isVolatile = FALSE;
int isVirtual = FALSE;
bool isInline = false;
int isIO = FALSE;
int isConst = FALSE;
bool isRegister = false;
bool isAuto = false;
bool isFuncBody;
bool isFuncPtr;
int missingArgumentName = FALSE;
int disableSubs;
int parsingParameterList = FALSE;
int unnamedCnt = 0;
int needParseFunction = 0;
int isStructDecl = FALSE;
int worstAlignment = 0;
char *stkname = 0;
std::string *classname;
bool isPrivate = true;
SYM *currentClass;
int mangledNames = FALSE;
 
/* variable for bit fields */
static int		bit_max;	// largest bitnumber
int bit_offset;	/* the actual offset */
int      bit_width;	/* the actual width */
int bit_next;	/* offset for next variable */
 
int declbegin(int st);
void dodecl(int defclass);
SYM *ParseDeclarationSuffix(SYM *);
void declstruct(int ztype);
void structbody(TYP *tp, int ztype);
void ParseEnumDeclaration(TABLE *table);
void enumbody(TABLE *table);
extern int ParseClassDeclaration(int ztype);
extern ENODE *ArgumentList(ENODE *hidden,int*,int);
TYP *nameref2(std::string name, ENODE **node,int nt,bool alloc,TypeArray*, TABLE* tbl);
SYM *search2(std::string na,TABLE *tbl,int *typearray);
SYM *gsearch2(std::string na, __int16, int *typearray, bool exact);
extern ENODE *makesnode(int,std::string *,std::string *,__int64);
 
extern TYP *CopyType(TYP *src);
 
int     imax(int i, int j)
{       return (i > j) ? i : j;
}
 
 
char *my_strdup(char *s)
{
	char *p;
	int n = strlen(s);
	int m = sizeof(char);
	p = (char *)allocx(sizeof(char)*(n+1));
	memcpy(p,s,sizeof(char)*(n));
	p[n] = '\0';
	return p;
}
 
void Declaration::SetType(SYM *sp)
{
	if (head) {
		if (bit_width <= 0) {
			sp->tp = head;
		}
		else {
			if (head->IsFloatType()) {
				sp->tp = head;
				sp->tp->precision = bit_width;
			}
			else if (head->IsVectorType()) {
				sp->tp = head;
				sp->tp->numele = bit_width;
			}
			else {
				sp->tp = TYP::Make(bt_bitfield,head->size);
				//  		*(sp->tp) = *head;
				sp->tp->bit_width = bit_width;
				sp->tp->bit_offset = bit_offset;
			}
		}
	}
	else {
		sp->tp = TYP::Make(bt_long,sizeOfWord);
		sp->tp->lst.head = sp->GetIndex();
	}
}
 
// Ignore const
void Declaration::ParseConst()
{
	isConst = TRUE;
	NextToken();
}
 
void Declaration::ParseTypedef()
{
	isTypedef = TRUE;
	NextToken();
}
 
void Declaration::ParseNaked()
{
	isNocall = TRUE;
	head = (TYP *)TYP::Make(bt_oscall,2);
	tail = head;
	NextToken();
}
 
void Declaration::ParseVoid()
{
	head = (TYP *)TYP::Make(bt_void,0);
	tail = head;
	head->isVolatile = isVolatile;
	head->isIO = isIO;
	head->isConst = isConst;
	NextToken();
	if (lastst==kw_interrupt) {
		isInterrupt = TRUE;
		NextToken();
	}
	if (lastst==kw_nocall || lastst==kw_naked) {
		isNocall = TRUE;
		NextToken();
	}
	bit_max = 0;
}
 
void Declaration::ParseShort()
{
	bit_max = 32;
	NextToken();
	switch(lastst) {
	case kw_int:
		NextToken();
		if (isUnsigned) {
			head = (TYP *)TYP::Make(bt_ushort,4);
			tail = head;
		}
		else {
			head = (TYP *)TYP::Make(bt_short,4);
			tail = head;
		}
		break;
	default:
		if (isUnsigned) {
			head = (TYP *)TYP::Make(bt_ushort,4);
			tail = head;
		}
		else {
			head = (TYP *)TYP::Make(bt_short,4);
			tail = head;
		}
		break;
	}
	head->isUnsigned = isUnsigned;
	head->isVolatile = isVolatile;
	head->isIO = isIO;
	head->isConst = isConst;
	head->isShort = TRUE;
}
 
void Declaration::ParseLong()
{
	NextToken();
	if (lastst==kw_int) {
		bit_max = 64;
		NextToken();
	}
	else if (lastst==kw_float) {
		head = (TYP *)TYP::Make(bt_double,8);
		tail = head;
		bit_max = head->precision;
		NextToken();
	}
	else if (lastst==kw_double) {
		head = TYP::Copy(&stddouble);
		//head = (TYP *)TYP::Make(bt_quad,8);
		tail = head;
		bit_max = head->precision;
		NextToken();
	}
	else {
		if (isUnsigned) {
			head =(TYP *)TYP::Make(bt_ulong,8);
			tail = head;
			bit_max = head->precision;
		}
		else {
			head = (TYP *)TYP::Make(bt_long,8);
			tail = head;
			bit_max = head->precision;
		}
	}
	//NextToken();
	if (lastst==kw_task) {
		isTask = TRUE;
		NextToken();
		bit_max = 64;
	}
	if (lastst==kw_oscall) {
		isOscall = TRUE;
		NextToken();
		bit_max = 64;
	}
	else if (lastst==kw_nocall || lastst==kw_naked) {
		isNocall = TRUE;
		NextToken();
		bit_max = 64;
	}
	head->isUnsigned = isUnsigned;
	head->isVolatile = isVolatile;
	head->isIO = isIO;
	head->isConst = isConst;
}
 
void Declaration::ParseInt()
{
//printf("Enter ParseInt\r\n");
	if (isUnsigned) {
		head = TYP::Make(bt_ulong,8);
		tail = head;
	}
	else {
		head = TYP::Make(bt_long,8);
		tail = head;
	}
	bit_max = 64;
	if (head==nullptr)
		return;
	head->isUnsigned = isUnsigned;
	head->isVolatile = isVolatile;
	head->isIO = isIO;
	head->isConst = isConst;
	NextToken();
	if (lastst==kw_vector) {
		int btp = head->GetIndex();
		head = TYP::Make(bt_vector,512);
		head->numele = maxVL;
		head->btp = btp;
		tail = head;
		NextToken();
	}
	if (lastst==kw_task) {
		isTask = TRUE;
		NextToken();
	}
	if (lastst==kw_oscall) {
		isOscall = TRUE;
		NextToken();
	}
	else if (lastst==kw_nocall || lastst==kw_naked) {
		isNocall = TRUE;
		NextToken();
	}
//printf("Leave ParseInt\r\n");
}
 
void Declaration::ParseFloat()
{
	head = TYP::Copy(&stddouble);
	tail = head;
	head->isVolatile = isVolatile;
	head->isIO = isIO;
	head->isConst = isConst;
	NextToken();
	if (lastst==kw_vector) {
		int btp = head->GetIndex();
		head = TYP::Make(bt_vector,512);
		head->numele = maxVL;
		head->btp = btp;
		tail = head;
		NextToken();
	}
	bit_max = head->precision;
}
 
void Declaration::ParseDouble()
{
	head = (TYP *)TYP::Make(bt_double,8);
	tail = head;
	head->isVolatile = isVolatile;
	head->isIO = isIO;
	head->isConst = isConst;
	NextToken();
	if (lastst==kw_vector) {
		int btp = head->GetIndex();
		head = TYP::Make(bt_vector,512);
		head->numele = maxVL;
		head->btp = btp;
		tail = head;
		NextToken();
	}
	bit_max = head->precision;
}
 
void Declaration::ParseTriple()
{
	head = (TYP *)TYP::Make(bt_triple, 12);
	head->precision = 96;
	tail = head;
	head->isVolatile = isVolatile;
	head->isIO = isIO;
	head->isConst = isConst;
	NextToken();
	if (lastst == kw_vector) {
		int btp = head->GetIndex();
		head = TYP::Make(bt_vector, 512);
		head->numele = maxVL;
		head->btp = btp;
		tail = head;
		NextToken();
	}
	bit_max = head->precision;
}
 
void Declaration::ParseFloat128()
{
	head = (TYP *)TYP::Make(bt_quad, 16);
	tail = head;
	head->precision = 128;
	head->isVolatile = isVolatile;
	head->isIO = isIO;
	head->isConst = isConst;
	NextToken();
	if (lastst == kw_vector) {
		int btp = head->GetIndex();
		head = TYP::Make(bt_vector, 512);
		head->numele = maxVL;
		head->btp = btp;
		tail = head;
		NextToken();
	}
	bit_max = head->precision;
}
 
void Declaration::ParseVector()
{
	int btp;
 
	head = (TYP *)TYP::Make(bt_double,sizeOfFPD);
	tail = head;
	head->isVolatile = isVolatile;
	head->isIO = isIO;
	head->isConst = isConst;
	NextToken();
	btp = head->GetIndex();
	head = TYP::Make(bt_vector,512);
	head->numele = maxVL;
	head->btp = btp;
	tail = head;
	NextToken();
	bit_max = head->precision;
}
 
void Declaration::ParseVectorMask()
{
	head = (TYP *)TYP::Make(bt_vector_mask,sizeOfWord);
	tail = head;
	head->isVolatile = isVolatile;
	head->isIO = isIO;
	head->isConst = isConst;
	head->numele = maxVL;
	NextToken();
	bit_max = head->precision;
}
 
void Declaration::ParseInt32()
{
	if (isUnsigned) {
		head = (TYP *)TYP::Make(bt_ushort,4);
		tail = head;
	}
	else {
		head = (TYP *)TYP::Make(bt_short,4);
		tail = head;
	}
	bit_max = 32;
	NextToken();
	if( lastst == kw_int )
		NextToken();
	head->isUnsigned = isUnsigned;
	head->isVolatile = isVolatile;
	head->isIO = isIO;
	head->isConst = isConst;
	head->isShort = TRUE;
}
 
void Declaration::ParseInt64()
{
	if (isUnsigned) {
		head = (TYP *)TYP::Make(bt_ulong,8);
		tail = head;
	}
	else {
		head = (TYP *)TYP::Make(bt_long,8);
		tail = head;
	}
	bit_max = 64;
	NextToken();
	if( lastst == kw_int )
		NextToken();
	head->isUnsigned = isUnsigned;
	head->isVolatile = isVolatile;
	head->isIO = isIO;
	head->isConst = isConst;
	head->isShort = TRUE;
}
 
void Declaration::ParseInt16()
{
	if (isUnsigned) {
		head = (TYP *)TYP::Make(bt_uchar,2);
		tail = head;
	}
	else {
		head =(TYP *)TYP::Make(bt_char,2);
		tail = head;
	}
	head->isUnsigned = isUnsigned;
	head->isVolatile = isVolatile;
	head->isIO = isIO;
	head->isConst = isConst;
	NextToken();
	if (lastst==kw_oscall) {
		isOscall = TRUE;
		NextToken();
	}
	if (lastst==kw_nocall || lastst==kw_naked) {
		isNocall = TRUE;
		NextToken();
	}
	bit_max = 16;
}
 
void Declaration::ParseInt8()
{
	if (isUnsigned) {
		head = (TYP *)TYP::Make(bt_ubyte,1);
		tail = head;
	}
	else {
		head =(TYP *)TYP::Make(bt_byte,1);
		tail = head;
	}
	head->isUnsigned = isUnsigned;
	head->isVolatile = isVolatile;
	head->isIO = isIO;
	head->isConst = isConst;
	NextToken();
	if (lastst==kw_oscall) {
		isOscall = TRUE;
		NextToken();
	}
	if (lastst==kw_nocall || lastst==kw_naked) {
		isNocall = TRUE;
		NextToken();
	}
	bit_max = head->precision;
}
 
void Declaration::ParseByte()
{
	if (isUnsigned) {
		head = (TYP *)TYP::Make(bt_ubyte,1);
		tail = head;
	}
	else {
		head =(TYP *)TYP::Make(bt_byte,1);
		tail = head;
	}
	NextToken();
	head->isUnsigned = !isSigned;
	head->isVolatile = isVolatile;
	head->isIO = isIO;
	head->isConst = isConst;
	bit_max = head->precision;
}
 
SYM *Declaration::ParseId()
{
	SYM *sp;
 
  dfs.printf("<ParseId>%s",lastid);
	sp = tagtable.Find(lastid,false);//gsyms[0].Find(lastid);
	if (sp==nullptr)
		sp = gsyms[0].Find(lastid,false);
	if (sp) {
		dfs.printf("Actually found type.\r\n");
		if (sp->storage_class==sc_typedef || sp->storage_class==sc_type) {
			NextToken();
			head = tail = sp->tp;
		}
		else
			head = tail = sp->tp;
//					head = tail = maketype(bt_long,4);
	}
	else {
		head = (TYP *)TYP::Make(bt_long,8);
		tail = head;
		bit_max = head->precision;
	}
	dfs.puts("</ParseId>");
	return (sp);
}
 
// Parse a specifier. This is the first part of a declaration.
// Returns:
// 0 usually, 1 if only a specifier is present
//
int Declaration::ParseSpecifier(TABLE *table)
{
	SYM *sp;
 
	dfs.printf("<ParseSpecifier>\n");
	isUnsigned = FALSE;
	isSigned = FALSE;
	isVolatile = FALSE;
	isVirtual = FALSE;
	isIO = FALSE;
	isConst = FALSE;
	dfs.printf("A");
	for (;;) {
		switch (lastst) {
 
			case kw_const:		ParseConst();	break;
			case kw_typedef:	ParseTypedef(); break;
			case kw_nocall:
			case kw_naked:		ParseNaked();	break;
 
			case kw_oscall:
				isOscall = TRUE;
				head = tail = (TYP *)TYP::Make(bt_oscall,2);
				NextToken();
				goto lxit;
 
			case kw_interrupt:
				isInterrupt = TRUE;
				head = (TYP *)TYP::Make(bt_interrupt,2);
				tail = head;
				NextToken();
				if (lastst==openpa) {
                    NextToken();
                    if (lastst!=id) 
                       error(ERR_IDEXPECT);
                    needpunc(closepa,49);
                    stkname = my_strdup(lastid);
                }
				goto lxit;
 
      case kw_virtual:
        dfs.printf("virtual");
        isVirtual = TRUE;
        NextToken();
        break;
 
			case kw_kernel:
				isKernel = TRUE;
				head =(TYP *) TYP::Make(bt_kernel,2);
				tail = head;
				NextToken();
				goto lxit;
 
			case kw_pascal:
				isPascal = TRUE;
				NextToken();
				break;
 
			case kw_inline:
				isInline = TRUE;
				NextToken();
				break;
 
			case kw_register:
				isRegister = TRUE;
				NextToken();
				break;
 
			// byte and char default to unsigned unless overridden using
			// the 'signed' keyword
			//
			case kw_byte:   ParseByte(); goto lxit;
			case kw_char:	ParseInt16(); goto lxit;
			case kw_int8:	ParseInt8(); goto lxit;
			case kw_int16:	ParseInt16(); goto lxit;
			case kw_int32:	ParseInt32(); goto lxit;
			case kw_int64:	ParseInt64(); goto lxit;
			case kw_short:	ParseShort();	goto lxit;
			case kw_long:	ParseLong();	goto lxit;	// long, long int
			case kw_int:	ParseInt();		goto lxit;
 
            case kw_task:
                isTask = TRUE;
                NextToken();
				break;
 
			case kw_signed:
				isSigned = TRUE;
				NextToken();
				break;
 
			case kw_unsigned:
				NextToken();
				isUnsigned = TRUE;
				break;
 
			case kw_volatile:
				NextToken();
				if (lastst==kw_inout) {
                    NextToken();
                    isIO = TRUE;
                }
				isVolatile = TRUE;
				break;
 
			case ellipsis:
				head = (TYP *)TYP::Make(bt_ellipsis,4);
				tail = head;
				head->isVolatile = isVolatile;
				head->isIO = isIO;
				head->isConst = isConst;
				NextToken();
				bit_max = 32;
				goto lxit;
 
			case id:	sp = ParseId();	goto lxit;
 
			case kw_float:	ParseFloat(); goto lxit;
			case kw_double:	ParseDouble(); goto lxit;
			case kw_float128:	ParseFloat128(); goto lxit;
 
			case kw_triple:
				head = TYP::Copy(&stdtriple);
				tail = head;
				head->isVolatile = isVolatile;
				head->isIO = isIO;
				head->isConst = isConst;
				NextToken();
				bit_max = head->precision;
				goto lxit;
 
			case kw_vector:	ParseVector(); goto lxit;
			case kw_vector_mask: ParseVectorMask(); goto lxit;
 
			case kw_void:	ParseVoid(); goto lxit;
 
			case kw_enum:
				NextToken();
				ParseEnumDeclaration(table);
				bit_max = 16;
				goto lxit;
 
			case kw_class:
				ClassDeclaration::Parse(bt_class);
				goto lxit;
 
			case kw_struct:
				NextToken();
				if (StructDeclaration::Parse(bt_struct))
					return 1;
				goto lxit;
 
			case kw_union:
				NextToken();
				if (StructDeclaration::Parse(bt_union))
					return 1;
				goto lxit;
 
      case kw_exception:
				head = (TYP *)TYP::Make(bt_exception,8);
				tail = head;
				head->isVolatile = isVolatile;
				head->isIO = isIO;
				head->isConst = isConst;
				NextToken();
				bit_max = 64;
				goto lxit;
 
			default:
				goto lxit;
			}
	}
lxit:;
	dfs.printf("</ParseSpecifier>\n");
	return 0;
}
 
void Declaration::ParseDoubleColon(SYM *sp)
{
	SYM *sym;
	bool gotDouble = false;
 
	while (lastst==double_colon) {
		gotDouble = true;
		sym = tagtable.Find(lastid,false);
		if (sym)
			sp->parent = sym->GetIndex();//gsearch(lastid);
		else {
			sp->parent = 0;
			break;
		}
		NextToken();
		if (lastst != id) {
			error(ERR_IDEXPECT);
			break;
		}
	}
	if (gotDouble)
	    NextToken();
	currentClass = sp->GetParentPtr();
	if (sp->parent)
		dfs.printf("Setting parent:%s|\r\n",
	(char *)sp->GetParentPtr()->name->c_str());
}
 
void Declaration::ParseBitfieldSpec(bool isUnion)
{
	dfs.puts("<ParseBitfieldSpec>");
	NextToken();
	bit_width = (int)GetIntegerExpression((ENODE **)NULL);
	if (isUnion)
		bit_offset = 0;
	else
		bit_offset = bit_next;
	if (bit_width < 0 || bit_width > bit_max) {
		error(ERR_BITFIELD_WIDTH);
		bit_width = 1;
	}
	if (bit_width == 0 || bit_offset + bit_width > bit_max)
		bit_offset = 0;
	bit_next = bit_offset + bit_width;
	dfs.puts("</ParseBitfieldSpec>\n");
}
 
SYM *Declaration::ParsePrefixId()
{
	SYM *sp;
 
	dfs.puts("<ParsePrefixId>");            
	if (declid) delete declid;
	declid = new std::string(lastid);
	dfs.printf("B|%s|",(char *)declid->c_str());
	sp = allocSYM();
	dfs.printf("C"); 
	if (funcdecl==1) {
		sp->fi = allocFunction(sp->id);
		sp->fi->sym = sp;
		if (nparms > 19)
			error(ERR_TOOMANY_PARAMS);
		else {
			names[nparms].str = *declid;
			nparms++;
		}
	}
	dfs.printf("D"); 
	NextToken();
	ParseDoubleColon(sp);
	if (declid) delete declid;
	declid = new std::string(lastid);
	sp->SetName(*declid);
	dfs.printf("E"); 
	if (lastst == colon) {
		ParseBitfieldSpec(isUnion);
		goto lxit;	// no ParseDeclarationSuffix()
	}
	sp->SetName(*declid);
	sp = ParseSuffix(sp);
	lxit:
	dfs.puts("</ParsePrefixId>");
	return sp;
}
 
SYM *Declaration::ParsePrefixOpenpa(bool isUnion)
{
	TYP *temp1, *temp2, *temp3, *temp4;
	SYM *sp;
 
	dfs.puts("<ParsePrefixOpenpa>\n");
	NextToken();
	temp1 = head;
	temp2 = tail;
	head = tail = (TYP *)NULL;	// It might be a typecast following.
	// Do we have (getchar)()
	// This processing is difficult to do with a loop, so a recursive
	// call is made.
	sp = ParsePrefix(isUnion); 
	needpunc(closepa,20);
	// Head could be NULL still if a type hasn't been found
	// eg. int (getchar)();
	if (head)
		isFuncPtr = head->type == bt_pointer;
	temp3 = head;
	temp4 = tail;
	head = temp1;
	tail = temp2;
	sp = ParseSuffix(sp);
	// (getchar)() returns temp4 = NULL
	if (temp4!=NULL) {
		temp4->btp = head->GetIndex();
		if(temp4->type == bt_pointer && temp4->val_flag != 0 && head != NULL)
			temp4->size *= head->size;
		head = temp3;
	}
	dfs.puts("</ParsePrefixOpenpa>\n");
	return sp;
}
 
// There may be only a single identifier in the prefix. This identifier may
// contain a class spec or namespace spec.
 
SYM *Declaration::ParsePrefix(bool isUnion)
{   
	TYP *temp1;
	SYM *sp;
 
	dfs.printf("<ParseDeclPrefix>(%d)\n",lastst);
 
	sp = nullptr;
j1:
	switch (lastst) {
 
	case kw_const:
		isConst = TRUE;
		NextToken();
		goto j1; 
 
//		case ellipsis:
	case id:
		sp = ParsePrefixId();
		goto lxit;
 
	case star:
		bit_max = 64;
		dfs.putch('*');
		temp1 = TYP::Make(bt_pointer,sizeOfPtr);
		temp1->btp = head->GetIndex();
		head = temp1;
		if(tail == NULL)
			tail = head;
		NextToken();
		if (lastst==closepa)
			goto lxit;
		sp = ParsePrefix(isUnion);
		goto lxit;
 
	case openpa:
		sp = ParsePrefixOpenpa(isUnion);
		goto lxit;
 
	default:
		sp = ParseSuffix(sp);
		dfs.printf("Z");
		goto lxit;
	}
lxit:
	dfs.puts("</ParseDeclPrefix>\n");
	return sp;
}
 
 
// Take care of trailing [] in a declaration. These indicate array indicies.
 
void Declaration::ParseSuffixOpenbr()
{
	TYP *temp1;
	long sz2;
 
	NextToken();
	temp1 = (TYP *)TYP::Make(bt_pointer,sizeOfPtr);
	temp1->val_flag = 1;
	temp1->isArray = TRUE;
	temp1->btp = head->GetIndex();
	if(lastst == closebr) {
		temp1->size = 0;
		temp1->numele = 0;
		if (head)
			temp1->dimen = head->dimen + 1;
		else
			temp1->dimen = 1;
		NextToken();
	}
	else if(head != NULL) {
		sz2 = (int)GetIntegerExpression((ENODE **)NULL);
		temp1->size = sz2 * head->size;
		temp1->numele = sz2;
		temp1->dimen = head->dimen + 1;
		dfs.printf("Setting array size:%d\n", (int)temp1->size);
		temp1->alignment = head->alignment;
		needpunc(closebr,21);
	}
	else {
		sz2 = (int)GetIntegerExpression((ENODE **)NULL);
		temp1->size = sz2;
		temp1->numele = sz2;
		temp1->dimen = 1;
		needpunc(closebr,22);
	}
	head = temp1;
	if( tail == NULL)
		tail = head;
}
 
void Declaration::ParseFunctionAttribute(Function *sym)
{
	NextToken();
	needpunc(openpa,0);
	do {
		switch(lastst) {
		case kw_no_temps:
			sym->UsesTemps = false;
			NextToken();
			break;
		/*
		case kw_no_parms:
			sym->UsesStackParms = false;
			NextToken();
			break;
		*/
		}
	} while (lastst==comma);
	needpunc(closepa,0);
}
 
 
// Take care of following open parenthesis (). These indicate a function
// call. There may or may not be following parameters. A following '{' is
// looked for and if found a flag is set to parse the function body.
 
void Declaration::ParseSuffixOpenpa(Function *sp)
{
	TYP *temp1;
	TYP *tempHead, *tempTail;
	int fd;
	std::string odecl;
	int isd;
	int nump = 0;
	int numa = 0;
	Function *cf;
 
	dfs.printf("<openpa>\n");
	dfs.printf("****************************\n");
	dfs.printf("****************************\n");
	dfs.printf("Function: %s\n", (char *)sp->sym->name->c_str());
	dfs.printf("****************************\n");
	dfs.printf("****************************\n");
	NextToken();
	sp->IsPascal = isPascal;
	sp->IsInline = isInline;
 
	// An asterik before the function name indicates a function pointer but only
	// if it's bracketed properly, otherwise it could be the return value that's
	// a pointer.
	//  isFuncPtr = head->type==bt_pointer;
	temp1 =(TYP *) TYP::Make(bt_func,0/*isFuncPtr ? bt_func : bt_ifunc,0*/);
	temp1->val_flag = 1;
	dfs.printf("o ");
	if (isFuncPtr) {
		dfs.printf("Got function pointer in declarations.\n");
		temp1->btp = head->btp;
		head->btp = temp1->GetIndex();
	}
	else {
		temp1->btp= head->GetIndex();
		head = temp1;
	}
	dfs.printf("p ");
	if (tail==NULL) {
		if (temp1->GetBtp())
			tail = temp1->GetBtp();
		else
			tail = temp1;
	}
	dfs.printf("q ");
	needParseFunction = 1;
	sp->params.Clear();
	sp->sym->parent = currentClass->GetIndex();
	if(lastst == closepa) {
		NextToken();
		while (lastst == kw_attribute)
			ParseFunctionAttribute(sp);
	  if(lastst == begin) {
		  temp1->type = bt_ifunc;
		  needParseFunction = 2;
	  }
	  else {
		  if (lastst != semicolon) {
				goto j2;
			cf = currentFn;
			currentFn = sp;
			nump = 0;
			sp->BuildParameterList(&nump, &numa);
			currentFn = cf;
			if (lastst==begin) {
				temp1->type = bt_ifunc;
				currentFn = sp;
				sp->NumParms = nump;
				sp->numa = numa;
				needParseFunction = 2;
				goto j1;
			}
		}
	      temp1->type = bt_func;
		  needParseFunction = 0;
		  dfs.printf("Set false\n");
	  }
	  currentFn = sp;
	  sp->NumParms = 0;
	  sp->numa = 0;
j1: ;
  }
  else {
j2:
    dfs.printf("r");
	  currentFn = sp;
    dfs.printf("s");
    temp1->type = bt_func;
  	// Parse the parameter list for a function pointer passed as a
  	// parameter.
  	// Parse parameter list for a function pointer defined within
  	// a structure.
  	if (parsingParameterList || isStructDecl) {
      dfs.printf("s ");
  		fd = funcdecl;
  		needParseFunction = FALSE;
  	  dfs.printf("Set false\n");
		if (declid)
  			odecl = *declid;
		else
			odecl = "";
  		tempHead = head;
  		tempTail = tail;
  		isd = isStructDecl;
  		//ParseParameterDeclarations(10);	// parse and discard
  		funcdecl = 10;
  //				SetType(sp);
  		sp->BuildParameterList(&nump, &numa);
  		needParseFunction = 0;
  	  dfs.printf("Set false\n");
  //				sp->parms = sym;
  		sp->NumParms = nump;
  		isStructDecl = isd;
  		head = tempHead;
  		tail = tempTail;
  		if (declid) delete declid;
  		declid = new std::string(odecl);
  		funcdecl = fd;
		// There may be more parameters in the list.
		if (lastst==comma) {
			return;
		}
  		needpunc(closepa,23);
 
  		if (lastst==begin) {
  		  needParseFunction = 2;
  		  dfs.printf("Set true1\n");
  			if (sp->params.GetHead() && sp->proto.GetHead()) {
  			  dfs.printf("Matching parameter types to prototype.\n");
  			  if (!sp->ParameterTypesMatch(sp))
  			     error(ERR_PARMLIST_MISMATCH);
  		  }
  			temp1->type = bt_ifunc;
  		}
  		// If the declaration is ending in a semicolon then it was really
  		// a function prototype, so move the parameters to the prototype
  		// area.
  		else if (lastst==semicolon) {
  			sp->params.CopyTo(&sp->proto);
      }
  	  else {
		if (funcdecl > 0 && lastst==closepa)
			;
		else
  			error(ERR_SYNTAX);
  	  }
      dfs.printf("Z\r\n");
//				if (isFuncPtr)
//					temp1->type = bt_func;
//				if (lastst != begin)
//					temp1->type = bt_func;
//				if (lastst==begin) {
//					ParseFunction(sp);
//				}
    }
    dfs.printf("Y");
	  sp->PrintParameterTypes();
    dfs.printf("X");
  }
  dfs.printf("</openpa>\n");
}
 
 
// Take care of the () or [] trailing part of a declaration.
// There could be multiple sets of [] so a loop is formed to accomodate
// this. There will be only a single set of () indicating parameters.
 
SYM *Declaration::ParseSuffix(SYM *sp)
{
	dfs.printf("<ParseDeclSuffix>\n");
 
	while(true) {
		switch (lastst) {
 
		case openbr:
			ParseSuffixOpenbr();  
			break;                // We want to loop back for more brackets
 
		case openpa:
			// The declaration doesn't have to have an identifier name; it could
			// just be a type chain. so sp incoming might be null. We need a place
			// to stuff the parameter / protoype list so we may as well create
			// the symbol here if it isn't yet defined.
			if (sp == nullptr) {
				sp = allocSYM();
				sp->fi = allocFunction(sp->id);
				sp->fi->sym = sp;
			}
			else if (sp->fi == nullptr) {
				sp->fi = allocFunction(sp->id);
				sp->fi->sym = sp;
			}
			ParseSuffixOpenpa(sp->fi);
			goto lxit;
 
		default:
			goto lxit;
		}
	}
lxit:
	dfs.printf("</ParseDeclSuffix>\n");
	return (sp);
}
 
void Declaration::AssignParameterName()
{
	char buf[20];
 
	sprintf_s(buf, sizeof(buf), "_p%d", nparms);
	delete declid;
	declid = new std::string(buf);
	if (nparms > 19) {
		error(ERR_TOOMANY_PARAMS);
	}
	else {
		names[nparms].str = *declid;
		nparms++;
	}
	missingArgumentName = TRUE;
}
 
 
int Declaration::GenStorage(int nbytes, int al, int ilc)
{
	static long old_nbytes;
	int bcnt;
 
	if (bit_width > 0 && bit_offset > 0) {
		// share the storage word with the previously defined field
		nbytes = old_nbytes - ilc;
	}
	old_nbytes = ilc + nbytes;
	dfs.printf("E");
	if ((ilc + nbytes) % head->roundAlignment()) {
		if (al == sc_thread)
			tseg();
		else
			dseg();
	}
	bcnt = 0;
	while ((ilc + nbytes) % head->roundAlignment()) {
		++nbytes;
		bcnt++;
	}
	if (al != sc_member && al != sc_external && al != sc_auto) {
		if (bcnt > 0)
			genstorage(bcnt);
	}
	return (nbytes);
}
 
 
/*
 *      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 Declaration::declare(SYM *parent,TABLE *table,int al,int ilc,int ztype)
{ 
	SYM *sp;
	SYM *sp1;
	Function *fn;
	TYP *dhead, *tp1, *tp2;
	ENODE *ep1, *ep2;
	int op;
	int fn_doneinit = 0;
	bool flag;
	int parentBytes = 0;
	std::string name;
 
    int nbytes;
 
	dfs.printf("Enter declare()\r\n");
	nbytes = 0;
	dfs.printf("A");
	classname = new std::string("");
	sp1 = nullptr;
	if (ParseSpecifier(table))
		goto xit1;
	dfs.printf("B");
	dhead = head;
	for(;;) {
	    if (declid) delete declid;
		declid = nullptr;
		dfs.printf("b");
		bit_width = -1;
		sp = ParsePrefix(ztype==bt_union);
		if (declid==nullptr)
			declid = new std::string("");
		// 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->length()==0)
			AssignParameterName();
 
		dfs.printf("C");
		if( declid->length() > 0 || classname->length()!=0) {      // otherwise just struct tag...
			if (sp == nullptr) {
				sp = allocSYM();
			}
			SetType(sp);
			if (funcdecl > 0) {
				sp->fi = allocFunction(sp->id);
				sp->fi->sym = sp;
				sp->fi->IsPascal = isPascal;
				sp->fi->IsInline = isInline;
			}
			sp->IsRegister = isRegister;
			isRegister = false;
			sp->IsAuto = isAuto;
			sp->IsParameter = parsingParameterList > 0;
			if (sp->parent < 0)// was nullptr
				sp->parent = parent->GetIndex();
			if (al==sc_member)
				sp->IsPrivate = isPrivate;
			else
				sp->IsPrivate = false;
			//if (declid==nullptr)
			//	declid = new std::string("");
			sp->SetName(classname->length() > 0 ? *classname : *declid);
			dfs.printf("D");
			if (classname) delete classname;
			classname = new std::string("");
			if (sp->tp->type == bt_func || sp->tp->type == bt_ifunc)
				sp->fi->IsVirtual = isVirtual;
			sp->storage_class = al;
			sp->isConst = isConst;
			if (isConst)
				sp->tp->isConst = TRUE;
			if (al != sc_member) {
				//							sp->isTypedef = isTypedef;
				if (isTypedef)
					sp->storage_class = sc_typedef;
				isTypedef = FALSE;
			}
 
			nbytes = GenStorage(nbytes, al, ilc);
/*
      dfs.printf("F");
		  if (sp->parent) {
        dfs.printf("f:%d",sp->parent);
        if (sp->GetParentPtr()->tp==nullptr) {
          dfs.printf("f:%d",sp->parent);
          dfs.printf("null type pointer.\n");
          parentBytes = 0;
        }
        else {
			    parentBytes = sp->GetParentPtr()->tp->size;
			    dfs.printf("ParentBytes=%d\n",parentBytes);
		    }
		  }
		  else
			  parentBytes = 0;
*/
			dfs.printf("G");
			if ((sp->tp->type == bt_func) && sp->storage_class == sc_global)
				sp->storage_class = sc_external;
 
			// Set the (struct member) storage offset.
			sp->SetStorageOffset(head, nbytes, al, ilc, ztype);
 
			// Increase the storage allocation by the type size.
			nbytes = sp->AdjustNbytes(nbytes, al, ztype);
 
			dfs.printf("H");
			// For a class declaration there may not be any variables declared as
			// part of the declaration. In that case the symbol name is an empty
			// string. There's nothing to insert in the symbol table.
			name = *sp->name;
			if (sp->name->length() > 0) {
				//dfs.printf("Table:%p, sp:%p Fn:%p\r\n", table, sp, currentFn);
				if (sp->parent) {
					int nn;
					// If a function body is being processed we want to look for
					// symbols by rising through the hierarchy. Otherwise we want a
					// lower level defined symbol to shadow one at a hight level.
					if (isFuncBody) {
						nn = sp->GetParentPtr()->tp->lst.FindRising(*sp->name);
						if (nn)
							sp1 = sp->FindRisingMatch(false);
					}
					else {
						nn = sp->GetParentPtr()->tp->lst.Find(*sp->name);
						if (nn) {
							sp1 = sp->fi->FindExactMatch(TABLE::matchno)->sym;
						}
					}
				}
				else
  					sp1 = table->Find(*sp->name,false);
 
				dfs.printf("h");
				if (sp->tp) {
					dfs.printf("h1");
					if (sp->tp->type == bt_ifunc || sp->tp->type==bt_func) {
						dfs.printf("h2");
						fn = sp->fi->FindExactMatch(TABLE::matchno);
						if (fn)
							sp1 = fn->sym;
						else
							sp1 = nullptr;
						dfs.printf("i");
					}
				}
				else {
  dfs.printf("j");
					if (TABLE::matchno)
						sp1 = TABLE::match[TABLE::matchno-1];
					else
						sp1 = nullptr;
				}
  dfs.printf("k");
  				flag = false;
	  			if (sp1) {
  					if (sp1->tp) {
  dfs.printf("l");
  						flag = sp1->tp->type == bt_func;
  					}
  				}
  dfs.printf("I");
  			if (sp->tp->type == bt_ifunc && flag)
  			{
  dfs.printf("Ia");
  				dfs.printf("bt_ifunc\r\n");
  				sp1->SetType(sp->tp);
  				sp1->storage_class = sp->storage_class;
			  sp1->value.i = sp->value.i;
			  if (!sp1->fi) {
				  sp1->fi = allocFunction(sp1->id);
				  sp1->fi->sym = sp1;
			  }
	          sp1->fi->IsPascal = sp->fi->IsPascal;
  				sp1->fi->IsPrototype = sp->fi->IsPrototype;
  				sp1->fi->IsVirtual = sp->fi->IsVirtual;
  				sp1->parent = sp->parent;
  				sp1->fi->params = sp->fi->params;
  				sp1->fi->proto = sp->fi->proto;
  				sp1->lsyms = sp->lsyms;
  				sp = sp1;
              }
  			else {
  dfs.printf("Ib");
  				// Here the symbol wasn't found in the table.
  				if (sp1 == nullptr) {
  dfs.printf("Ic");
            if ((sp->tp->type==bt_class)
               && (sp->storage_class == sc_type || sp->storage_class==sc_typedef))
              ; // Do nothing. The class was already entered in the tag table.
            else if ((sp->tp->type == bt_struct || sp->tp->type==bt_union)
               && (sp->storage_class == sc_type && sp->storage_class!=sc_typedef)
               && sp->tp->sname->length() > 0)
              ; // If there was no struct tag and this is a typedef, then it
                // still needs to be inserted into the table.
            else {
              dfs.printf("insert type: %d\n", sp->tp->type);
  					  dfs.printf("***Inserting:%s into %p\n",(char *)sp->name->c_str(), (char *) table);
  					   // Need to know the type before a name can be generated.
					  if (sp->tp->type == bt_func || sp->tp->type == bt_ifunc)
						sp->mangledName = sp->BuildSignature(!sp->fi->IsPrototype);
   					  if (sp->parent && ((sp->tp->type==bt_func || sp->tp->type==bt_ifunc)
   					  || (sp->tp->type==bt_pointer && (sp->tp->GetBtp()->type==bt_func || sp->tp->GetBtp()->type==bt_ifunc))))
              {
						  sp->fi->InsertMethod();
  			      }
  			      else {
                table->insert(sp);
  					  }
  				  }
  				}
  			}
  dfs.printf("J");
  			if (needParseFunction) {
  				needParseFunction = FALSE;
  				fn_doneinit = sp->fi->Parse();
  				if (sp->tp->type != bt_pointer)
  					return (nbytes);
  			}
     //         if(sp->tp->type == bt_ifunc) { /* function body follows */
     //             ParseFunction(sp);
     //             return nbytes;
     //         }
  dfs.printf("K");
              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;
		}
 
		// If semi-colon is encountered we are at the end of the declaration.
		else if (lastst == semicolon) {
			if (sp) {
				if (sp->tp) {
					if (sp->tp->type==bt_class && (sp->storage_class != sc_type
						&& sp->storage_class != sc_typedef)) {
						int nn;
						nn = sp->tp->lst.FindRising(*sp->tp->sname);
						if (nn > 0) {
							if (sp1) {
								ENODE *ep1,*ep2;
								ep1 = nullptr;
  								// Build an expression that references the ctor.
  								tp1 = nameref2(*sp->tp->sname,&ep1,TRUE,false,nullptr,nullptr);
  								// Create a function call node for the ctor.
  								if (tp1!=nullptr) {
  									// Make an expresison that references the var name as the
  									// argument to the ctor.
  									ep2 = makesnode(en_nacon,sp->name,sp->mangledName,sp->value.i);
  									ep1 = makenode(en_fcall, ep1, ep2);
  								}
  								sp->initexp = ep1;
							}
						}
		/*
						// First see if there is a ctor. If there are no ctors there's
						// nothing to do.
						memset(typearray,0,sizeof(typearray));
						sp1 = search2(sp->tp->sname,&sp->tp->lst,typearray);
						if (sp1) {
							// Build an expression that references the ctor.
							tp1 = nameref2(sp->tp->sname,&ep1,TRUE,false,typearray);
							// Create a function call node for the ctor.
							if (tp1!=nullptr) {
								memcpy(typearray,GetParameterTypes(sp),sizeof(typearray));
								ep1 = makenode(en_fcall, ep1, nullptr);
							}
							sp->initexp = ep1;
						}
		*/
					}
				}
			}
			break;	// semicolon
		}
 
		// Handle an assignment
		else if (lastst == assign) {
			tp1 = nameref(&ep1,TRUE);
            op = en_assign;
//            NextToken();
            tp2 = asnop(&ep2);
            if( tp2 == 0 || !IsLValue(ep1) )
                error(ERR_LVALUE);
            else {
                tp1 = forcefit(&ep1,tp1,&ep2,tp2,false);
                ep1 = makenode(op,ep1,ep2);
            }
			sp->initexp = ep1;
			if (lastst==semicolon)
				break;
		}
 
		// See if there is a list of variable declarations
        needpunc(comma,24);
        if(declbegin(lastst) == 0)
            break;
        head = dhead;
    }
    NextToken();
xit1:
//	printf("Leave declare()\r\n");
    return (nbytes);
}
 
int declbegin(int st)
{
	return st == star || st == id || st == openpa || st == openbr; 
}
 
void GlobalDeclaration::Parse()
{
	dfs.puts("<ParseGlobalDecl>\n");
	for(;;) {
		lc_auto = 0;
		bool notVal = false;
		isFuncPtr = false;
		isPascal = FALSE;
		isInline = false;
		currentClass = nullptr;
		currentFn = nullptr;
		currentStmt = nullptr;
		isFuncBody = false;
		worstAlignment = 0;
		funcdecl = 0;
 
		switch(lastst) {
		case kw_pascal:
		  NextToken();
		  isPascal = TRUE;
		  break;
		case kw_inline:
		  NextToken();
		  isInline = true;
		  break;
		case ellipsis:
		case id:
        case kw_kernel:
		case kw_interrupt:
        case kw_task:
		case kw_cdecl:
		case kw_naked:
		case kw_nocall:
		case kw_oscall:
		case kw_typedef:
    case kw_virtual:
		case kw_volatile: case kw_const:
        case kw_exception:
		case kw_int8: case kw_int16: case kw_int32: case kw_int64: case kw_int40: case kw_int80:
		case kw_byte: case kw_char: case kw_int: case kw_short: case kw_unsigned: case kw_signed:
        case kw_long: case kw_struct: case kw_union: case kw_class:
        case kw_enum: case kw_void:
        case kw_float: case kw_double: case kw_float128:
		case kw_vector: case kw_vector_mask:
                lc_static += declare(NULL,&gsyms[0],sc_global,lc_static,bt_struct);
				isInline = false;
				break;
        case kw_thread:
				NextToken();
                lc_thread += declare(NULL,&gsyms[0],sc_thread,lc_thread,bt_struct);
				isInline = false;
				break;
		case kw_register:
				NextToken();
                error(ERR_ILLCLASS);
                lc_static += declare(NULL,&gsyms[0],sc_global,lc_static,bt_struct);
				isInline = false;
				break;
		case kw_private:
        case kw_static:
                NextToken();
				lc_static += declare(NULL,&gsyms[0],sc_static,lc_static,bt_struct);
				isInline = false;
                break;
    case kw_extern:
        NextToken();
				if (lastst==kw_pascal) {
					isPascal = TRUE;
					NextToken();
				}
				if (lastst==kw_kernel) {
					isKernel = TRUE;
					NextToken();
				}
				else if (lastst==kw_oscall || lastst==kw_interrupt || lastst==kw_nocall || lastst==kw_naked)
					NextToken();
          ++global_flag;
          declare(NULL,&gsyms[0],sc_external,0,bt_struct);
          isInline = false;
          --global_flag;
          break;
 
    case kw_not:
      NextToken();
      notVal = !notVal;
      break;
 
    case kw_using:
      NextToken();
      if (lastst==id) {
        if (strcmp(lastid,"_name")==0) {
          NextToken();
          if (lastst==id) {
            if (strcmp(lastid, "_mangler")==0) {
              NextToken();
              mangledNames = !notVal;
            }
          }
        }
        else if (strcmp(lastid,"_real")==0) {
          NextToken();
          if (lastst==id) {
            if (strcmp(lastid,"_names")==0) {
              NextToken();
              mangledNames = notVal;
            }
          }
        }
      }
	  else if (lastst==kw_short) {
		  NextToken();
		  if (lastst==id) {
			  if (strcmp(lastid,"_pointers")==0)
				  sizeOfPtr = 4;
		  }
	  }
	  else if (lastst==kw_long) {
		  NextToken();
		  if (lastst==id) {
			  if (strcmp(lastid,"_pointers")==0)
				  sizeOfPtr = 8;
		  }
	  }
      break;
 
    default:
      goto xit;
		}
	}
xit:
	dfs.puts("</ParseGlobalDecl>\n");
	;
}
 
void AutoDeclaration::Parse(SYM *parent, TABLE *ssyms)
{
	SYM *sp;
 
//	printf("Enter ParseAutoDecls\r\n");
    for(;;) {
		funcdecl = 0;
		isFuncPtr = false;
		worstAlignment = 0;
		switch(lastst) {
		case kw_cdecl:
    case kw_kernel:
		case kw_interrupt:
		case kw_naked:
		case kw_nocall:
		case kw_oscall:
		case kw_pascal:
		case kw_typedef:
                error(ERR_ILLCLASS);
	            lc_auto += declare(parent,ssyms,sc_auto,lc_auto,bt_struct);
				break;
		case ellipsis:
		case id: //return;
        dfs.printf("Found %s\n", lastid);
				sp = tagtable.Find(lastid,false);
				if (sp)
				   dfs.printf("Found in tagtable");
				if (sp==nullptr)
					sp = gsyms[0].Find(lastid,false);
				if (sp) {
				  dfs.printf("sp okay sc=%d\n", sp->storage_class);
					if (sp->storage_class==sc_typedef || sp->storage_class==sc_type) {
					  dfs.printf("Declaring var of type\n");
			            lc_auto += declare(parent,ssyms,sc_auto,lc_auto,bt_struct);
						break;
					}
				}
				goto xit;
        case kw_register:
                NextToken();
        case kw_exception:
		case kw_volatile: case kw_const:
		case kw_int8: case kw_int16: case kw_int32: case kw_int64: case kw_int40: case kw_int80:
		case kw_byte: case kw_char: case kw_int: case kw_short: case kw_unsigned: case kw_signed:
        case kw_long: case kw_struct: case kw_union: case kw_class:
        case kw_enum: case kw_void:
        case kw_float: case kw_double: case kw_float128:
		case kw_vector: case kw_vector_mask:
            lc_auto += declare(parent,ssyms,sc_auto,lc_auto,bt_struct);
            break;
        case kw_thread:
                NextToken();
				lc_thread += declare(parent,ssyms,sc_thread,lc_thread,bt_struct);
				break;
        case kw_static:
                NextToken();
				lc_static += declare(parent,ssyms,sc_static,lc_static,bt_struct);
				break;
        case kw_extern:
                NextToken();
				if (lastst==kw_oscall || lastst==kw_interrupt || lastst == kw_nocall || lastst==kw_naked || lastst==kw_kernel)
					NextToken();
                ++global_flag;
                declare(NULL,&gsyms[0],sc_external,0,bt_struct);
                --global_flag;
                break;
        default:
                goto xit;
		}
	}
xit:
	;
//	printf("Leave ParseAutoDecls\r\n");
}
 
int ParameterDeclaration::Parse(int fd)
{
	int ofd;
  int opascal;
 
	dfs.puts("<ParseParmDecls>\n");
	ofd = funcdecl;
	opascal = isPascal;
	isPascal = FALSE;
	funcdecl = fd;
	parsingParameterList++;
	nparms = 0;
	for(;;) {
		worstAlignment = 0;
		isFuncPtr = false;
		isAuto = false;
		isRegister = false;
		missingArgumentName = FALSE;
		dfs.printf("A(%d)",lastst);
j1:
		switch(lastst) {
		case kw_auto:
			NextToken();
			isAuto = true;
			goto j1;
		case kw_pascal:
			NextToken();
		  isPascal = TRUE;
		  goto j1;
		case kw_cdecl:
    case kw_kernel:
		case kw_interrupt:
		case kw_naked:
		case kw_nocall:
		case kw_oscall:
		case kw_typedef:
dfs.printf("B");
      error(ERR_ILLCLASS);
      declare(NULL,&currentFn->params,sc_auto,0,bt_struct);
				isAuto = false;
			break;
		case ellipsis:
		case id:
		case kw_volatile: case kw_const:
        case kw_exception:
		case kw_int8: case kw_int16: case kw_int32: case kw_int64: case kw_int40: case kw_int80:
		case kw_byte: case kw_char: case kw_int: case kw_short: case kw_unsigned: case kw_signed:
    case kw_long: case kw_struct: case kw_union: case kw_class:
    case kw_enum: case kw_void:
	case kw_float: case kw_double: case kw_float128:
	case kw_vector: case kw_vector_mask:
dfs.printf("C");
    declare(NULL,&currentFn->params,sc_auto,0,bt_struct);
				isAuto = false;
	            break;
        case kw_thread:
                NextToken();
                error(ERR_ILLCLASS);
				lc_thread += declare(NULL,&gsyms[0],sc_thread,lc_thread,bt_struct);
				isAuto = false;
				break;
        case kw_static:
                NextToken();
                error(ERR_ILLCLASS);
				lc_static += declare(NULL,&gsyms[0],sc_static,lc_static,bt_struct);
				isAuto = false;
				break;
        case kw_extern:
dfs.printf("D");
                NextToken();
                error(ERR_ILLCLASS);
				if (lastst==kw_oscall || lastst==kw_interrupt || lastst == kw_nocall || lastst==kw_naked || lastst==kw_kernel)
					NextToken();
                ++global_flag;
                declare(NULL,&gsyms[0],sc_external,0,bt_struct);
				isAuto = false;
                --global_flag;
                break;
		case kw_register:
				isRegister = true;
				NextToken();
				goto j1;
        default:
				goto xit;
		}
dfs.printf("E");
	}
xit:
	parsingParameterList--;
	funcdecl = ofd;
	isPascal = opascal;
	dfs.printf("</ParseParmDecls>\n");
	return nparms;
}
 
GlobalDeclaration *GlobalDeclaration::Make()
{
  GlobalDeclaration *p = (GlobalDeclaration *)allocx(sizeof(GlobalDeclaration));
  return p;
}
 
void compile()
{
}
 
 

Compare with Previous | Blame | View Log

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.