+RESULT_TYPE
+getResultTypeFromType (sym_link *type)
+{
+ /* type = getSpec (type); */
+ if (IS_BIT (type))
+ return RESULT_TYPE_BIT;
+ if (IS_BITFIELD (type))
+ {
+ int blen = SPEC_BLEN (type);
+
+ if (blen <= 1)
+ return RESULT_TYPE_BIT;
+ if (blen <= 8)
+ return RESULT_TYPE_CHAR;
+ return RESULT_TYPE_INT;
+ }
+ if (IS_CHAR (type))
+ return RESULT_TYPE_CHAR;
+ if ( IS_INT (type)
+ && !IS_LONG (type))
+ return RESULT_TYPE_INT;
+ return RESULT_TYPE_OTHER;
+}
+
+/*-----------------------------------------------------------------*/
+/* addCast - adds casts to a type specified by RESULT_TYPE */
+/*-----------------------------------------------------------------*/
+static ast *
+addCast (ast *tree, RESULT_TYPE resultType, bool upcast)
+{
+ sym_link *newLink;
+ bool upCasted = FALSE;
+
+ switch (resultType)
+ {
+ case RESULT_TYPE_NONE:
+ /* char: promote to int */
+ if (!upcast ||
+ getSize (tree->etype) >= INTSIZE)
+ return tree;
+ newLink = newIntLink();
+ upCasted = TRUE;
+ break;
+ case RESULT_TYPE_CHAR:
+ if (getSize (tree->etype) <= 1)
+ return tree;
+ newLink = newCharLink();
+ break;
+ case RESULT_TYPE_INT:
+#if 0
+ if (getSize (tree->etype) > INTSIZE)
+ {
+ /* warn ("Loosing significant digits"); */
+ return;
+ }
+#endif
+ /* char: promote to int */
+ if (!upcast ||
+ getSize (tree->etype) >= INTSIZE)
+ return tree;
+ newLink = newIntLink();
+ upCasted = TRUE;
+ break;
+ case RESULT_TYPE_OTHER:
+ if (!upcast)
+ return tree;
+ /* return type is long, float: promote char to int */
+ if (getSize (tree->etype) >= INTSIZE)
+ return tree;
+ newLink = newIntLink();
+ upCasted = TRUE;
+ break;
+ default:
+ return tree;
+ }
+ tree->decorated = 0;
+ tree = newNode (CAST, newAst_LINK (newLink), tree);
+ tree->lineno = tree->right->lineno;
+ /* keep unsigned type during cast to smaller type,
+ but not when promoting from char to int */
+ if (!upCasted)
+ SPEC_USIGN (tree->left->opval.lnk) = IS_UNSIGNED (tree->right->etype) ? 1 : 0;
+ return decorateType (tree, resultType);
+}
+
+/*-----------------------------------------------------------------*/
+/* resultTypePropagate - decides if resultType can be propagated */
+/*-----------------------------------------------------------------*/
+static RESULT_TYPE
+resultTypePropagate (ast *tree, RESULT_TYPE resultType)
+{
+ switch (tree->opval.op)
+ {
+ case '=':
+ case '?':
+ case ':':
+ case '|':
+ case '^':
+ case '*':
+ case '+':
+ case '-':
+ case LABEL:
+ return resultType;
+ case '&':
+ if (!tree->right)
+ /* can be unary */
+ return RESULT_TYPE_NONE;
+ else
+ return resultType;
+ case IFX:
+ return RESULT_TYPE_IFX;
+ default:
+ return RESULT_TYPE_NONE;
+ }
+}
+
+/*-----------------------------------------------------------------*/
+/* getLeftResultType - gets type from left branch for propagation */
+/*-----------------------------------------------------------------*/
+static RESULT_TYPE
+getLeftResultType (ast *tree, RESULT_TYPE resultType)
+{
+ switch (tree->opval.op)
+ {
+ case '=':
+ case CAST:
+ if (IS_PTR (LTYPE (tree)))
+ return RESULT_TYPE_NONE;
+ else
+ return getResultTypeFromType (LETYPE (tree));
+ case RETURN:
+ if (IS_PTR (currFunc->type->next))
+ return RESULT_TYPE_NONE;
+ else
+ return getResultTypeFromType (currFunc->type->next);
+ case '[':
+ if (!IS_ARRAY (LTYPE (tree)))
+ return resultType;
+ if (DCL_ELEM (LTYPE (tree)) > 0 && DCL_ELEM (LTYPE (tree)) <= 256)
+ return RESULT_TYPE_CHAR;
+ return resultType;
+ default:
+ return resultType;
+ }
+}
+
+/*--------------------------------------------------------------------*/
+/* decorateType - compute type for this tree, also does type checking.*/
+/* This is done bottom up, since type has to flow upwards. */
+/* resultType flows top-down and forces e.g. char-arithmetik, if the */
+/* result is a char and the operand(s) are int's. */
+/* It also does constant folding, and parameter checking. */
+/*--------------------------------------------------------------------*/