more function pointer parameter issues
[fw/sdcc] / src / SDCCsymt.c
index 27eb61915394f9f8d6bc68954995842c430745b1..d19342b5faa11f98638a465218c0201b1f863839 100644 (file)
 
 value *aggregateToPointer (value *val);
 
+void printFromToType(sym_link *from, sym_link *to) {
+  fprintf (stderr, "from type '");
+  printTypeChain (from, stderr);
+  fprintf (stderr, "'\nto type '");
+  printTypeChain (to, stderr);
+  fprintf (stderr, "'\n");
+}
+
 /* noun strings */
 char *nounName(sym_link *sl) {
   switch (SPEC_NOUN(sl)) 
@@ -107,11 +115,13 @@ addSym (bucket ** stab,
   bucket *bp;                  /* temp bucket    *         */
 
   if (checkType) {
+    symbol *csym = (symbol *)sym;
+
     if (getenv("DEBUG_SANITY")) {
       fprintf (stderr, "addSym: %s ", sname);
     }
     /* make sure the type is complete and sane */
-    checkTypeSanity(((symbol *)sym)->etype, ((symbol *)sym)->name);
+    checkTypeSanity(csym->etype, csym->name);
   }
 
   /* prevent overflow of the (r)name buffers */
@@ -400,6 +410,9 @@ addDecl (symbol * sym, int type, sym_link * p)
   sym_link *tail;
   sym_link *t;
 
+  if (getenv("SDCC_DEBUG_FUNCTION_POINTERS"))
+    fprintf (stderr, "SDCCsymt.c:addDecl(%s,%d,%p)\n", sym->name, type, p);
+
   /* if we are passed a link then set head & tail */
   if (p)
     {
@@ -462,6 +475,12 @@ addDecl (symbol * sym, int type, sym_link * p)
       SPEC_VOLATILE (sym->etype) = SPEC_VOLATILE (DCL_TSPEC (p));
       DCL_TSPEC (p) = NULL;
     }
+
+  // if there is a function in this type chain
+  if (p && funcInChain(sym->type)) {
+    processFuncArgs (sym);
+  }
+
   return;
 }
 
@@ -541,12 +560,14 @@ mergeSpec (sym_link * dest, sym_link * src, char *name)
   sym_link *symlink=dest;
 
   if (!IS_SPEC(dest) || !IS_SPEC(src)) {
+#if 0
     werror (E_INTERNAL_ERROR, __FILE__, __LINE__, "cannot merge declarator");
     exit (1);
-  }
-
-  if (getenv("DEBUG_mergeSpec")) {
-    fprintf (stderr, "mergeSpec: \"%s\"\n", name);
+#else
+    werror (E_SYNTAX_ERROR, yytext);
+    // the show must go on
+    return newIntLink();
+#endif
   }
 
   if (SPEC_NOUN(src)) {
@@ -592,6 +613,7 @@ mergeSpec (sym_link * dest, sym_link * src, char *name)
   dest->select.s._signed|=src->select.s._signed;
   SPEC_STAT (dest) |= SPEC_STAT (src);
   SPEC_EXTR (dest) |= SPEC_EXTR (src);
+  SPEC_CONST(dest) |= SPEC_CONST (src);
   SPEC_ABSA (dest) |= SPEC_ABSA (src);
   SPEC_VOLATILE (dest) |= SPEC_VOLATILE (src);
   SPEC_ADDR (dest) |= SPEC_ADDR (src);
@@ -1086,10 +1108,12 @@ compStructSize (int su, structdef * sdef)
            sum += getSize (loop->type);
        }
 
+#if 0 // jwk: this is done now in addDecl()
        /* if function then do the arguments for it */
        if (funcInChain (loop->type)) {
-           processFuncArgs (loop, 1);
+           processFuncArgs (loop);
        }
+#endif
 
        loop = loop->next;
 
@@ -1119,9 +1143,6 @@ checkSClass (symbol * sym, int isProto)
   if (getenv("DEBUG_SANITY")) {
     fprintf (stderr, "checkSClass: %s \n", sym->name);
   }
-  if (strcmp(sym->name, "_testsGlobal")==0) {
-    printf ("oach\n");
-  }
   
   /* type is literal can happen foe enums change
      to auto */
@@ -1452,6 +1473,7 @@ compareType (sym_link * dest, sym_link * src)
            int res=compareType (dest, val->type);
            Safe_free(val->type);
            Safe_free(val);
+           //return res ? -1 : 0;
            return res;
          }
          if (IS_PTR (dest) && IS_FUNC (dest->next) && IS_FUNC (src))
@@ -1560,6 +1582,11 @@ aggregateToPointer (value * val)
          DCL_TYPE (val->type) = PPOINTER;
          break;
        case S_FIXED:
+         if (SPEC_OCLS(val->etype)) {
+           DCL_TYPE(val->type)=PTR_TYPE(SPEC_OCLS(val->etype));
+           break;
+         }
+
          if (TARGET_IS_DS390)
            {
              /* The AUTO and REGISTER classes should probably
@@ -1669,12 +1696,7 @@ checkFunction (symbol * sym, symbol *csym)
   if (compareType (csym->type, sym->type) <= 0)
     {
       werror (E_PREV_DEF_CONFLICT, csym->name, "type");
-      werror (W_CONTINUE, "previous definition type ");
-      printTypeChain (csym->type, stderr);
-      fprintf (stderr, "\n");
-      werror (W_CONTINUE, "current definition type ");
-      printTypeChain (sym->type, stderr);
-      fprintf (stderr, "\n");
+      printFromToType(csym->type, sym->type);
       return 0;
     }
 
@@ -1725,6 +1747,7 @@ checkFunction (symbol * sym, symbol *csym)
       if (compareType (exargs->type, checkValue->type) <= 0)
        {
          werror (E_ARG_TYPE, argCnt);
+         printFromToType(exargs->type, checkValue->type);
          return 0;
        }
     }
@@ -1750,27 +1773,36 @@ checkFunction (symbol * sym, symbol *csym)
 /* processFuncArgs - does some processing with function args       */
 /*-----------------------------------------------------------------*/
 void 
-processFuncArgs (symbol * func, int ignoreName)
+processFuncArgs (symbol * func)
 {
   value *val;
   int pNum = 1;
+  sym_link *funcType=func->type;
+
+  if (getenv("SDCC_DEBUG_FUNCTION_POINTERS"))
+    fprintf (stderr, "SDCCsymt.c:processFuncArgs(%s)\n", func->name);
+
+  // if this is a pointer to a function
+  if (IS_PTR(funcType)) {
+    funcType=funcType->next;
+  }
 
   /* if this function has variable argument list */
   /* then make the function a reentrant one    */
-  if (IFFUNC_HASVARARGS(func->type))
-    FUNC_ISREENT(func->type)=1;
+  if (IFFUNC_HASVARARGS(funcType))
+    FUNC_ISREENT(funcType)=1;
 
   /* check if this function is defined as calleeSaves
      then mark it as such */
-  FUNC_CALLEESAVES(func->type) = inCalleeSaveList (func->name);
+  FUNC_CALLEESAVES(funcType) = inCalleeSaveList (func->name);
 
   /* loop thru all the arguments   */
-  val = FUNC_ARGS(func->type);
+  val = FUNC_ARGS(funcType);
 
   /* if it is void then remove parameters */
   if (val && IS_VOID (val->type))
     {
-      FUNC_ARGS(func->type) = NULL;
+      FUNC_ARGS(funcType) = NULL;
       return;
     }
 
@@ -1783,7 +1815,7 @@ processFuncArgs (symbol * func, int ignoreName)
       /* mark it as a register parameter if
          the function does not have VA_ARG
          and as port dictates */
-      if (!IFFUNC_HASVARARGS(func->type) &&
+      if (!IFFUNC_HASVARARGS(funcType) &&
          (*port->reg_parm) (val->type))
        {
          SPEC_REGPARM (val->etype) = 1;
@@ -1793,6 +1825,7 @@ processFuncArgs (symbol * func, int ignoreName)
        {
          aggregateToPointer (val);
        }
+
       val = val->next;
       pNum++;
     }
@@ -1801,17 +1834,17 @@ processFuncArgs (symbol * func, int ignoreName)
   if (func->cdef) {
     /* ignore --stack-auto for this one, we don't know how it is compiled */
     /* simply trust on --int-long-reent or --float-reent */
-    if (IFFUNC_ISREENT(func->type)) {
+    if (IFFUNC_ISREENT(funcType)) {
       return;
     }
   } else {
     /* if this function is reentrant or */
     /* automatics r 2b stacked then nothing */
-    if (IFFUNC_ISREENT (func->type) || options.stackAuto)
+    if (IFFUNC_ISREENT (funcType) || options.stackAuto)
       return;
   }
 
-  val = FUNC_ARGS(func->type);
+  val = FUNC_ARGS(funcType);
   pNum = 1;
   while (val)
     {
@@ -1890,7 +1923,7 @@ printTypeChain (sym_link * start, FILE * of)
     }
 
   if (start==NULL) {
-    fprintf (of, "**err**");
+    fprintf (of, "void");
     return;
   }
 
@@ -1913,43 +1946,43 @@ printTypeChain (sym_link * start, FILE * of)
            case GPOINTER:
              if (DCL_PTR_CONST (type))
                fprintf (of, "const ");
-             fprintf (of, "* generic ");
+             fprintf (of, "generic * ");
              break;
            case CPOINTER:
              if (DCL_PTR_CONST (type))
                fprintf (of, "const ");
-             fprintf (of, "* code ");
+             fprintf (of, "code * ");
              break;
            case FPOINTER:
              if (DCL_PTR_CONST (type))
                fprintf (of, "const ");
-             fprintf (of, "* xdata ");
+             fprintf (of, "xdata * ");
              break;
            case EEPPOINTER:
              if (DCL_PTR_CONST (type))
                fprintf (of, "const ");
-             fprintf (of, "* eeprom ");
+             fprintf (of, "eeprom * ");
              break;
 
            case POINTER:
              if (DCL_PTR_CONST (type))
                fprintf (of, "const ");
-             fprintf (of, "* near ");
+             fprintf (of, "near *");
              break;
            case IPOINTER:
              if (DCL_PTR_CONST (type))
                fprintf (of, "const ");
-             fprintf (of, "* idata ");
+             fprintf (of, "idata * ");
              break;
            case PPOINTER:
              if (DCL_PTR_CONST (type))
                fprintf (of, "const ");
-             fprintf (of, "* pdata ");
+             fprintf (of, "pdata * ");
              break;
            case UPOINTER:
              if (DCL_PTR_CONST (type))
                fprintf (of, "const ");
-             fprintf (of, "* unkown ");
+             fprintf (of, "unkown * ");
              break;
            case ARRAY:
              fprintf (of, "[] ");