**/
while (bp)
{
-
if (strcmp (bp->name, sym->name) == 0 && bp->level <= sym->level)
{
/* if this is parameter then nothing else need to be checked */
if (((symbol *) (bp->sym))->_isparm)
return (bp->sym);
- /* if levels match then block numbers hsould also match */
+ /* if levels match then block numbers should also match */
if (bp->level && bp->level == sym->level && bp->block == sym->block)
return (bp->sym);
/* if levels don't match then we are okay */
ptr = ptr->next;
/* could not find it */
- if (!ptr || IS_SPEC (ptr) ||
- DCL_TYPE (ptr) != UPOINTER)
+ if (!ptr || IS_SPEC (ptr))
+ return;
+
+ if (IS_PTR(ptr) && DCL_TYPE(ptr)!=UPOINTER) {
+ pointerTypes (ptr->next, type);
return;
+ }
/* change the pointer type depending on the
storage class of the type */
}
}
- /* if the type is a unknown pointer and has
+ /* if the type is an unknown pointer and has
a tspec then take the storage class const & volatile
attribute from the tspec & make it those of this
symbol */
if (p &&
!IS_SPEC (p) &&
- DCL_TYPE (p) == UPOINTER &&
+ //DCL_TYPE (p) == UPOINTER &&
DCL_TSPEC (p))
{
if (!IS_SPEC (sym->etype))
/*------------------------------------------------------------------*/
/* mergeSpec - merges two specifiers and returns the new one */
/*------------------------------------------------------------------*/
-#define LAST_MINUTE_2_3_0_FIX
sym_link *
mergeSpec (sym_link * dest, sym_link * src, char *name)
{
-#ifdef LAST_MINUTE_2_3_0_FIX
- sym_link *symlink;
+ sym_link *symlink=dest;
+#if 0
if (!IS_SPEC(dest)) {
- // This should not happen
- fprintf (stderr, "*** internal error: can't merge declarators\n");
+ // This can happen for pointers, find the end type
+ while (dest && !IS_SPEC(dest))
+ dest=dest->next;
}
if (!IS_SPEC(src)) {
// here we have a declarator as source, reverse them
symlink=src;
src=dest;
dest=symlink;
- while (!IS_SPEC(dest)) {
+ while (dest && !IS_SPEC(dest)) {
// and find the specifier
dest=dest->next;
}
}
#endif
+ if (!IS_SPEC(dest) || !IS_SPEC(src)) {
+ werror (E_INTERNAL_ERROR, __FILE__, __LINE__, "cannot merge declarator");
+ exit (1);
+ }
+
if (getenv("DEBUG_mergeSpec")) {
fprintf (stderr, "mergeSpec: \"%s\"\n", name);
}
if (IS_STRUCT (dest) && SPEC_STRUCT (dest) == NULL)
SPEC_STRUCT (dest) = SPEC_STRUCT (src);
-#ifdef LAST_MINUTE_2_3_0_FIX
return symlink;
-#else
- return dest;
-#endif
}
/*------------------------------------------------------------------*/
symbol *sym = symHead;
symbol *csym = NULL;
-
for (; sym != NULL; sym = sym->next)
{
changePointer(sym);
+ checkTypeSanity(sym->etype, sym->name);
/* if already exists in the symbol table then check if
- the previous was an extern definition if yes then
+ one of them is an extern definition if yes then
then check if the type match, if the types match then
delete the current entry and add the new entry */
if ((csym = findSymWithLevel (SymbolTab, sym)) &&
- csym->level == sym->level)
- {
-
- /* previous definition extern ? */
- if (IS_EXTERN (csym->etype))
- {
- /* do types match ? */
- if (compareType (csym->type, sym->type) != 1)
- /* no then error */
- werror (E_DUPLICATE, csym->name);
-
- /* delete current entry */
- deleteSym (SymbolTab, csym, csym->name);
- /* add new entry */
- addSym (SymbolTab, sym, sym->name, sym->level, sym->block, 1);
- }
- else /* not extern */
- werror (E_DUPLICATE, sym->name);
+ csym->level == sym->level) {
+
+ /* one definition extern ? */
+ if (IS_EXTERN (csym->etype) || IS_EXTERN (sym->etype)) {
+ /* do types match ? */
+ if (compareType (csym->type, sym->type) != 1) {
+ /* no then error */
+ werror (E_EXTERN_MISMATCH, csym->name);
+ continue;
+ }
+ /* delete current entry */
+ deleteSym (SymbolTab, csym, csym->name);
+ } else {
+ /* not extern */
+ werror (E_DUPLICATE, sym->name);
continue;
}
+ }
- /* check if previously defined */
- if (csym && csym->level == sym->level)
- {
- /* if the previous one was declared as extern */
- /* then check the type with the current one */
- if (IS_EXTERN (csym->etype))
- {
- if (compareType (csym->type, sym->type) <= 0)
- werror (W_EXTERN_MISMATCH, csym->name);
- }
- }
+ /* add new entry */
addSym (SymbolTab, sym, sym->name, sym->level, sym->block, 1);
}
}
}
}
else {
- checkDecl (loop);
+ checkDecl (loop, 1);
sum += getSize (loop->type);
}
/* checkSClass - check the storage class specification */
/*------------------------------------------------------------------*/
static void
-checkSClass (symbol * sym)
+checkSClass (symbol * sym, int isProto)
{
if (getenv("DEBUG_SANITY")) {
fprintf (stderr, "checkSClass: %s \n", sym->name);
sym->ival = NULL;
}
-#if 0
- /* if this is an automatic symbol then */
- /* storage class will be ignored and */
- /* symbol will be allocated on stack/ */
- /* data depending on flag */
- if (sym->level &&
- (options.stackAuto || reentrant) &&
- (SPEC_SCLS (sym->etype) != S_AUTO &&
- SPEC_SCLS (sym->etype) != S_FIXED &&
- SPEC_SCLS (sym->etype) != S_REGISTER &&
- SPEC_SCLS (sym->etype) != S_STACK &&
- SPEC_SCLS (sym->etype) != S_XSTACK))
- {
- werror (E_AUTO_ASSUMED, sym->name);
- SPEC_SCLS (sym->etype) = S_AUTO;
- }
-#else
/* if this is an atomatic symbol */
if (sym->level && (options.stackAuto || reentrant)) {
if ((SPEC_SCLS (sym->etype) == S_AUTO ||
}
}
}
-#endif
/* automatic symbols cannot be given */
/* an absolute address ignore it */
SPEC_BSTR (sym->etype) = 0;
}
- /* variables declared in CODE space must have */
- /* initializers if not an extern */
- if (SPEC_SCLS (sym->etype) == S_CODE &&
- sym->ival == NULL &&
- !sym->level &&
- port->mem.code_ro &&
- !IS_EXTERN (sym->etype) &&
- !funcInChain (sym->type))
- werror (E_CODE_NO_INIT, sym->name);
+ if (!isProto) {
+ /* variables declared in CODE space must have */
+ /* initializers if not an extern */
+ if (SPEC_SCLS (sym->etype) == S_CODE &&
+ sym->ival == NULL &&
+ //!sym->level &&
+ port->mem.code_ro &&
+ !IS_EXTERN (sym->etype) &&
+ !funcInChain (sym->type))
+ werror (E_CODE_NO_INIT, sym->name);
+ }
/* if parameter or local variable then change */
/* the storage class to reflect where the var will go */
/* checkDecl - does semantic validation of a declaration */
/*------------------------------------------------------------------*/
int
-checkDecl (symbol * sym)
+checkDecl (symbol * sym, int isProto)
{
- checkSClass (sym); /* check the storage class */
+ checkSClass (sym, isProto); /* check the storage class */
changePointer (sym); /* change pointers if required */
/* if this is an array without any dimension
return rType;
}
-/*------------------------------------------------------------------*/
-/* compareType - will do type check return 1 if match */
-/*------------------------------------------------------------------*/
+/*--------------------------------------------------------------------*/
+/* compareType - will do type check return 1 if match, -1 if castable */
+/*--------------------------------------------------------------------*/
int
compareType (sym_link * dest, sym_link * src)
{
{
if (DCL_TYPE (src) == DCL_TYPE (dest))
return compareType (dest->next, src->next);
- else if (IS_PTR (src) && IS_PTR (dest))
+ if (IS_PTR (src) && IS_PTR (dest))
return -1;
- else if (IS_PTR (dest) && IS_ARRAY (src))
+ if (IS_PTR (dest) && IS_ARRAY (src))
return -1;
- else if (IS_PTR (dest) && IS_FUNC (dest->next) && IS_FUNC (src))
+ if (IS_PTR (dest) && IS_FUNC (dest->next) && IS_FUNC (src))
return -1 * compareType (dest->next, src);
- else
- return 0;
+ return 0;
}
else if (IS_PTR (dest) && IS_INTEGRAL (src))
return -1;
return -1;
if (SPEC_USIGN (dest) != SPEC_USIGN (src))
- return -2;
+ return -1;
return 1;
}
if (compareType (csym->type, sym->type) <= 0)
{
werror (E_PREV_DEF_CONFLICT, csym->name, "type");
- werror (E_CONTINUE, "previous definition type ");
+ werror (W_CONTINUE, "previous definition type ");
printTypeChain (csym->type, stderr);
fprintf (stderr, "\n");
- werror (E_CONTINUE, "current definition type ");
+ werror (W_CONTINUE, "current definition type ");
printTypeChain (sym->type, stderr);
fprintf (stderr, "\n");
return 0;
int bwd, su, muldivmod, tofrom, rlrr;
+ if (getenv("SDCC_NO_C_SUPPORT")) {
+ /* for debugging only */
+ return;
+ }
+
floatType = newFloatLink ();
for (bwd = 0; bwd < 3; bwd++)