sym->level = scope; /* set the level */
sym->block = currBlockno;
sym->lineDef = mylineno; /* set the line number */
+ sym->fileDef = currFname;
return sym;
}
sym_link *rType;
sym_link *reType;
sym_link *etype1 = getSpec (type1);
- sym_link *etype2 = getSpec (type2);
+ sym_link *etype2;
+
+ etype2 = type2 ? getSpec (type2) : type1;
/* if one of them is a float then result is a float */
/* here we assume that the types passed are okay */
if (IS_CHAR (reType) && promoteCharToInt)
SPEC_NOUN (reType) = V_INT;
- if ( ( ( SPEC_USIGN (etype1)
- /* if this operand is promoted to a larger
- type don't check it's signedness */
- && (getSize (etype1) >= getSize (reType))
- /* We store signed literals in the range 0...255 as
- 'unsigned char'. If there was no promotion to 'signed int'
- they must not force an unsigned operation: */
- && !(IS_CHAR (etype1) && IS_LITERAL (etype1)))
- || ( SPEC_USIGN (etype2)
- && (getSize (etype2) >= getSize (reType))
- && !(IS_CHAR (etype2) && IS_LITERAL (etype2))))
- && !IS_FLOAT (reType))
+ /* SDCC's sign promotion:
+ - if one or both operands are unsigned, the resultant type will be unsigned
+ (except char, see below)
+ - if an operand is promoted to a larger type (char -> int, int -> long),
+ the larger type will be signed
+
+ SDCC tries hard to avoid promotion to int and does 8 bit calculation as
+ much as possible. We're leaving ISO IEC 9899 here and have to extrapolate
+ the standard. The standard demands, that the result has to be the same
+ "as if" the promotion would have been performed:
+
+ - if the result of an operation with two char's is promoted to a
+ larger type, the result will be signed.
+
+ More sophisticated is the last one:
+ - if the result of an operation with two char's is a char again,
+ the result will only then be unsigned, if both operands are
+ unsigned. In all other cases the result will be signed.
+
+ This seems to be contradictionary to the first two rules, but it makes
+ real sense (all types are char's):
+
+ A signed char can be negative; this must be preserved in the result
+ -1 * 100 = -100;
+
+ Only if both operands are unsigned it's safe to make the result
+ unsigned; this helps to avoid overflow:
+ 2 * 100 = 200;
+
+ Homework: - why is (200 * 200 < 0) true?
+ - why is { char l = 200, r = 200; (r * l > 0) } true?
+ */
+
+ if (!IS_FLOAT (reType)
+ && ( (SPEC_USIGN (etype1)
+ /* if this operand is promoted to a larger type,
+ then it will be promoted to a signed type */
+ && !(getSize (etype1) < getSize (reType))
+ /* char require special handling */
+ && !IS_CHAR (etype1))
+ || /* same for 2nd operand */
+ (SPEC_USIGN (etype2)
+ && !(getSize (etype2) < getSize (reType))
+ && !IS_CHAR (etype2))
+ || /* if both are 'unsigned char' and not promoted
+ let the result be unsigned too */
+ ( SPEC_USIGN (etype1)
+ && SPEC_USIGN (etype2)
+ && IS_CHAR (etype1)
+ && IS_CHAR (etype2)
+ && IS_CHAR (reType))))
SPEC_USIGN (reType) = 1;
else
SPEC_USIGN (reType) = 0;
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)) {
+ /* find the function declaration within the type */
+ while (funcType && !IS_FUNC(funcType))
funcType=funcType->next;
- }
/* if this function has variable argument list */
/* then make the function a reentrant one */