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

Subversion Repositories thor

[/] [thor/] [trunk/] [FT64v5/] [software/] [CC64/] [source/] [Symbol.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"
 
char *prefix;
extern int nparms;
extern bool isRegister;
 
SYM *SYM::GetPtr(int n)
{ 
  if (n==0)
    return nullptr;
  if (n > 32767)
     return nullptr;
  return (SYM *)&compiler.symbolTable[n]; 
}
 
SYM *SYM::GetNextPtr()
{ 
  if (next==0)
     return nullptr;
  if (next > 32767)
     return nullptr;
  return &compiler.symbolTable[next];
}
 
SYM *SYM::GetParentPtr()
{
	if (parent==0)
	   return nullptr;
  if (parent > 32767)
     return nullptr;
   return &compiler.symbolTable[parent];
};
 
int SYM::GetIndex()
{
  if (this==nullptr)
     return 0; 
  return this - &compiler.symbolTable[0];
};
 
uint8_t hashadd(char *nm)
{
	uint8_t hsh;
 
	for(hsh=0;*nm;nm++)
		hsh += *nm;
	return hsh;
}
 
SYM *search2(std::string na,TABLE *tbl,TypeArray *typearray)
{
	SYM *thead;
	TypeArray *ta;
 
	if (na=="" || tbl==nullptr)
		return nullptr;
//	printf("Enter search2\r\n");
	if (tbl==&gsyms[0])
		thead = compiler.symbolTable[0].GetPtr(hashadd((char *)na.c_str()));
	else
		thead = &compiler.symbolTable[tbl->GetHead()];
	while( thead != NULL) {
		if (thead->name->length() != 0) {
		  /*
			if (prefix)
				strncpy(namebuf,prefix,sizeof(namebuf)-1);
			else
				namebuf[0]='\0';
			strncat(namebuf,thead->name,sizeof(namebuf)-1);
			*/
			if(thead->name->compare(na)==0) {
				if (typearray) {
					ta = thead->fi->GetProtoTypes();
					if (ta->IsEqual(typearray))
						break;
					if (ta)
						delete ta;
				}
				else
					break;
			}
		}
    thead = thead->GetNextPtr();
    }
//	printf("Leave search2\r\n");
    return (thead);
}
 
SYM *search(std::string na,TABLE *tbl)
{
	return search2(na,tbl,nullptr);
}
 
// first look in the current compound statement for the symbol,
// Next look in progressively more outer compound statements
// Next look in the local symbol table for the function
// Finally look in the global symbol table.
//
SYM *gsearch2(std::string na, __int16 rettype, TypeArray *typearray, bool exact)
{
	SYM *sp;
	Statement *st;
	SYM *p;
 
	dfs.printf("\n<gsearch2> for: |%s|\n", (char *)na.c_str());
	prefix = nullptr;
	sp = nullptr;
	// There might not be a current statement if global declarations are
	// being processed.
	if (currentStmt==NULL) {
	  dfs.printf("Stmt=null, looking in global table\n");
		if (gsyms[0].Find(na,rettype,typearray,exact)) {
			sp = TABLE::match[TABLE::matchno-1];
			dfs.printf("Found in global symbol table\n");
			dfs.puts("</gsearch2>\n");
			return sp;
		}
		dfs.puts("</gsearch2>\n");
		return nullptr;
	}
	else {
    dfs.printf("Looking in statement table\n");
		if (currentStmt->ssyms.Find(na,rettype,typearray,exact)) {
			sp = TABLE::match[TABLE::matchno-1];
     	dfs.printf("Found as an auto var\n");
			dfs.puts("</gsearch2>\n");
			return sp;
		}
		st = currentStmt->outer;
		while (st) {
    dfs.printf("Looking in outer statement table\n");
			if (st->ssyms.Find(na,rettype,typearray,exact)) {
				sp = TABLE::match[TABLE::matchno-1];
       	dfs.printf("Found as an auto var\n");
  			dfs.puts("</gsearch2>\n");
				return (sp);
			}
			st = st->outer;
		}
		p = currentFn->sym;
		if (p) {
      dfs.printf("Looking in function's symbol table\n");
  		if (currentFn->sym->lsyms.Find(na,rettype,typearray,exact)) {
  			sp = TABLE::match[TABLE::matchno-1];
       	dfs.printf("Found in function symbol table (a label)\n");
  			dfs.puts("</gsearch2>\n");
  			return (sp);
  		}
  		while(p) {
  			dfs.printf("Searching method/class:%s|%p\n",(char *)p->name->c_str(),(char *)p);
  			if (p->tp) {
    			if (p->tp->type != bt_class) {
      			dfs.printf("Looking at params %p\n",(char *)&p->fi->params);
      			if (p->fi->params.Find(na,rettype,typearray,exact)) {
      				sp = TABLE::match[TABLE::matchno-1];
             	dfs.printf("Found as parameter\n");
        			dfs.puts("</gsearch2>\n");
      				return (sp);
      			}
    		  }
    			// Search for class member
    			dfs.printf("Looking at class members %p\n",(char *)&p->tp->lst);
    			if (p->tp->type == bt_class) {
    			  SYM *tab;
    			  int nn;
    				if (p->tp->lst.Find(na,rettype,typearray,exact)) {
    					sp = TABLE::match[TABLE::matchno-1];
             	dfs.printf("Found in class\n");
        			dfs.puts("</gsearch2>\n");
    					return (sp);
    				}
    				dfs.printf("Base=%d",p->tp->lst.base);
    				tab = p->GetPtr(p->tp->lst.base);
    				dfs.printf("Base=%p",(char *)tab);
    				if (tab) {
    				  dfs.puts("Has a base class");
    				  if (tab->tp) {
           			dfs.printf("Looking at base class members:%p\n",(char *)tab);
        				nn = tab->tp->lst.FindRising(na);
        				if (nn > 0) {
                 	dfs.printf("Found in base class\n");
        				  if (exact) {
           				  //sp = sp->FindRisingMatch();
        				    sp = Function::FindExactMatch(TABLE::matchno, na, bt_long, typearray)->sym;
        				    if (sp) {
                			dfs.puts("</gsearch2>\n");
        				      return (sp);
      				      }
        				  }
        				  else {
    				        sp = TABLE::match[0];
                		dfs.puts("</gsearch2>\n");
    				        return (sp);
    				      }
    				    }
      				}
    			  }
  			  }
  			}
  			p = p->GetParentPtr();
  		}
  	}
		// Finally, look in the global symbol table
		dfs.printf("Looking at global symbols\n");
		if (gsyms[0].Find(na,rettype,typearray,exact)) {
			sp = TABLE::match[TABLE::matchno-1];
			dfs.printf("Found in global symbol table\n");
			dfs.puts("</gsearch2>\n");
			return (sp);
		}
	}
 
	dfs.puts("</gsearch2>\n");
  return (sp);
}
 
// A wrapper for gsearch2() when we only care about finding any match.
 
SYM *gsearch(std::string name)
{
	return (gsearch2(name, bt_long, nullptr, false));
}
 
 
// Create a copy of a symbol, used when creating derived classes from base
// classes. The type is copyied and extended by a derived class.
 
SYM *SYM::Copy(SYM *src)
{
	SYM *dst = nullptr;
 
  dfs.printf("Enter SYM::Copy\n");
	if (src) {
		dst = allocSYM();
		dfs.printf("A");
		memcpy(dst, src, sizeof(SYM));
//		dst->tp = TYP::Copy(src->tp);
//		dst->name = src->name;
//		dst->shortname = src->shortname;
		dst->SetNext(0);
		if (src->fi) {
			dst->fi = allocFunction(src->id);
			memcpy(dst->fi, src->fi, sizeof(Function));
			dst->fi->sym = dst;
			dst->fi->params.SetOwner(src->id);
			dst->fi->proto.SetOwner(src->id);
		}
  }
  dfs.printf("Leave SYM::Copy\n");
	return (dst);
}
 
SYM *SYM::Find(std::string nme)
{
	SYM *sp;
 
//	printf("Enter Find(char *)\r\n");
	sp = tp->lst.Find(nme,false);
	if (sp==nullptr) {
		if (parent) {
			sp = GetPtr(parent)->Find(nme);
		}
	}
//	printf("Leave Find(char *):%p\r\n",sp);
	return (sp);
}
 
int SYM::FindNextExactMatch(int startpos, TypeArray * tb)
{
	SYM *sp1;
	int nn;
	TypeArray *ta;
 
	sp1 = nullptr;
	for (nn = startpos; nn < TABLE::matchno; nn++) {
		sp1 = TABLE::match[nn];
		if (fi) {
			ta = sp1->fi->GetProtoTypes();
			if (ta->IsEqual(tb)) {
				delete ta;
				return (nn);
			}
			delete ta;
		}
	}
	return (-1);
}
 
 
SYM *SYM::FindRisingMatch(bool ignore)
{
	int nn;
	int em;
	int iter;
	SYM *s = this;
	std::string nme;
	TypeArray *ta = nullptr;
 
	nme = *name;
	if (fi)
		ta = fi->GetProtoTypes();
	dfs.printf("<FindRisingMatch>%s type %d ", (char *)name->c_str(), tp->type);
	if (GetParentPtr() != nullptr)
		nn = GetParentPtr()->tp->lst.FindRising(nme);
	else
		nn = 1;
	//  nn = tp->lst.FindRising(nme);
	iter = 0;
	if (nn) {
		dfs.puts("Found method:");
		for (iter = 0; true; iter = em + 1) {
			em = FindNextExactMatch(iter, ta);
			if (em < 0)
				break;
			s = TABLE::match[em];
			if (!ignore || s->GetParentPtr() != GetParentPtr()) { // ignore entry here
				dfs.puts("Found in a base class:");
				break;
			}
			s = nullptr;
		}
	}
	if (ta)
		delete ta;
	dfs.printf("</FindRisingMatch>\n");
	return (s);
}
 
 
// Convert a type number to a character string
// These will always be four characters.
 
std::string *TypenoToChars(int typeno)
{
	const char *alphabet =
		"ABCDEFGHIJKLMNOPQRSTUVWXYZ123456";
	char c[8];
	std::string *str;
 
  dfs.puts("<TypenoToChars>");
  str = new std::string();
  dfs.putch('A');
	c[0] = alphabet[typeno & 31];
  dfs.putch('B');
	c[1] = alphabet[(typeno>>5) & 31];
  dfs.putch('C');
	c[2] = alphabet[(typeno>>10) & 31];
  c[3] = alphabet[(typeno>>15) & 31];
  c[4] = '\0';
  c[5] = '\0';
  c[6] = '\0';
  c[7] = '\0';
  dfs.puts("D:");
	str->append(c);
	dfs.printf("%s",(char *)str->c_str());
  dfs.puts("</TypenoToChars>");
	return str;
}
 
// Get the mangled name for the function
//
std::string *SYM::GetNameHash()
{
	std::string *nh;
  SYM *sp;
  int nn;
 
  dfs.puts("<GetNameHash>");
  dfs.printf("tp:%p",(char *)tp);
//  if (tp==(TYP *)0x500000005LL) {
//    nh = new std::string("TAA");
//    return nh;
//  }
	nh = TypenoToChars(tp->typeno);
  dfs.putch('A');
  sp = GetParentPtr();
  if (sp) {
     nh->append(*sp->GetNameHash());
	   sp = GetPtr(sp->tp->lst.base);
     dfs.putch('B');
   	 for (nn = 0; sp && nn < 200; nn++) {
  	   dfs.putch('.');
  	   nh->append(*sp->GetNameHash());
       sp = GetPtr(sp->tp->lst.base);
  	 }
	   if (nn >= 200) {
	     error(ERR_CIRCULAR_LIST);
    }
	}
/*
	if (parent) {
	  sp = GetPtr(parent);
		nh += sp->GetNameHash();
	}
*/
  dfs.puts("</GetNameHash>\n");
	return nh;
}
 
// Build a function signature string including
// the return type, base classes, and any parameters.
 
std::string *SYM::BuildSignature(int opt)
{
	std::string *str;
	std::string *nh;
 
	dfs.printf("<BuildSignature>");
	if (this == nullptr) {
		str = new std::string("");
		str->append(*name);
		dfs.printf(":%s</BuildSignature>", (char *)str->c_str());
		return (str);
	}
	if (mangledNames) {
		str = new std::string("_Z");		// 'C' likes this
		dfs.printf("A");
		nh = GetNameHash();
		dfs.printf("B");
		str->append(*nh);
		dfs.printf("C");
		delete nh;
		dfs.printf("D");
		if (name > (std::string *)0x15)
			str->append(*name);
		if (opt) {
			dfs.printf("E");
			str->append(*fi->GetParameterTypes()->BuildSignature());
		}
		else {
			dfs.printf("F");
			str->append(*fi->GetProtoTypes()->BuildSignature());
		}
	}
	else {
		str = new std::string("");
		str->append(*name);
	}
	dfs.printf(":%s</BuildSignature>", (char *)str->c_str());
	return str;
}
 
 
// Called during declaration parsing.
 
// 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.
 
void SYM::SetStorageOffset(TYP *head, int nbytes, int al, int ilc, int ztype)
{
	// Set the struct member storage offset.
	if (al == sc_static || al == sc_thread) {
		value.i = nextlabel++;
	}
	else if (ztype == bt_union) {
		value.i = ilc;// + parentBytes;
	}
	else if (al != sc_auto) {
		value.i = ilc + nbytes;// + parentBytes;
	}
	else {
		value.i = -(ilc + nbytes + head->roundSize());// + parentBytes);
	}
}
 
 
// Increase the storage allocation by the type size.
 
int SYM::AdjustNbytes(int nbytes, int al, int ztype)
{
	if (ztype == bt_union)
		nbytes = imax(nbytes, tp->roundSize());
	else if (al != sc_external) {
		// If a pointer to a function is defined in a struct.
		if (isStructDecl) {
			if (tp->type == bt_func) {
				nbytes += 8;
			}
			else if (tp->type != bt_ifunc) {
				nbytes += tp->roundSize();
			}
		}
		else {
			nbytes += tp->roundSize();
		}
	}
	return (nbytes);
}
 
 

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.