1
0
mirror of https://github.com/cc65/cc65.git synced 2024-12-25 02:29:52 +00:00

Made char type a distinct type.

This commit is contained in:
acqn 2020-08-15 06:27:11 +08:00 committed by Oliver Schmidt
parent 87889df9e9
commit 56b659c0be
7 changed files with 53 additions and 30 deletions

View File

@ -59,6 +59,7 @@
/* Predefined type strings */
Type type_char[] = { TYPE(T_CHAR), TYPE(T_END) };
Type type_schar[] = { TYPE(T_SCHAR), TYPE(T_END) };
Type type_uchar[] = { TYPE(T_UCHAR), TYPE(T_END) };
Type type_int[] = { TYPE(T_INT), TYPE(T_END) };
@ -431,14 +432,6 @@ int SignExtendChar (int C)
TypeCode GetDefaultChar (void)
/* Return the default char type (signed/unsigned) depending on the settings */
{
return IS_Get (&SignedChars)? T_SCHAR : T_UCHAR;
}
Type* GetCharArrayType (unsigned Len)
/* Return the type for a char array of the given length */
{
@ -448,7 +441,7 @@ Type* GetCharArrayType (unsigned Len)
/* Fill the type string */
T[0].C = T_ARRAY;
T[0].A.L = Len; /* Array length is in the L attribute */
T[1].C = GetDefaultChar ();
T[1].C = T_CHAR;
T[2].C = T_END;
/* Return the new type */
@ -685,8 +678,9 @@ int TypeHasAttr (const Type* T)
const Type* GetUnderlyingType (const Type* Type)
/* Get the underlying type of an enum or other integer class type */
{
if (IsTypeEnum (Type)) {
if (IsISOChar (Type)) {
return IS_Get (&SignedChars) ? type_schar : type_uchar;
} else if (IsTypeEnum (Type)) {
/* This should not happen, but just in case */
if (Type->A.P == 0) {
Internal ("Enum tag type error in GetUnderlyingTypeCode");
@ -708,8 +702,11 @@ TypeCode GetUnderlyingTypeCode (const Type* Type)
TypeCode Underlying = UnqualifiedType (Type->C);
TypeCode TCode;
/* We could also support other T_CLASS_INT types, but just enums for now */
if (IsTypeEnum (Type)) {
if (IsISOChar (Type)) {
return IS_Get (&SignedChars) ? T_SCHAR : T_UCHAR;
} else if (IsTypeEnum (Type)) {
/* This should not happen, but just in case */
if (Type->A.P == 0) {
@ -996,7 +993,7 @@ int IsClassArithmetic (const Type* T)
int IsClassBasic (const Type* T)
/* Return true if this is a char, integer or floating type */
{
return IsRawTypeChar (T) || IsClassInt (T) || IsClassFloat (T);
return IsClassChar (T) || IsClassInt (T) || IsClassFloat (T);
}

View File

@ -117,7 +117,7 @@ enum {
T_MASK_QUAL = 0x07F000,
/* Types */
T_CHAR = T_TYPE_CHAR | T_CLASS_INT | T_SIGN_UNSIGNED | T_SIZE_CHAR,
T_CHAR = T_TYPE_CHAR | T_CLASS_INT | T_SIGN_NONE | T_SIZE_CHAR,
T_SCHAR = T_TYPE_CHAR | T_CLASS_INT | T_SIGN_SIGNED | T_SIZE_CHAR,
T_UCHAR = T_TYPE_CHAR | T_CLASS_INT | T_SIGN_UNSIGNED | T_SIZE_CHAR,
T_SHORT = T_TYPE_SHORT | T_CLASS_INT | T_SIGN_SIGNED | T_SIZE_SHORT,
@ -189,6 +189,7 @@ struct Type {
#define PTR_BITS (8 * SIZEOF_PTR)
/* Predefined type strings */
extern Type type_char[];
extern Type type_schar[];
extern Type type_uchar[];
extern Type type_int[];
@ -250,9 +251,6 @@ void TypeFree (Type* T);
int SignExtendChar (int C);
/* Do correct sign extension of a character */
TypeCode GetDefaultChar (void);
/* Return the default char type (signed/unsigned) depending on the settings */
Type* GetCharArrayType (unsigned Len);
/* Return the type for a char array of the given length */
@ -365,7 +363,7 @@ INLINE TypeCode GetRawType (const Type* T)
#if defined(HAVE_INLINE)
INLINE int IsTypeChar (const Type* T)
/* Return true if this is a character type */
/* Return true if this is a char type */
{
return (GetRawType (GetUnderlyingType (T)) == T_TYPE_CHAR);
}
@ -395,7 +393,7 @@ INLINE int IsTypeInt (const Type* T)
#if defined(HAVE_INLINE)
INLINE int IsTypeLong (const Type* T)
/* Return true if this is a long type (signed or unsigned) */
/* Return true if this is a long int type (signed or unsigned) */
{
return (GetRawType (GetUnderlyingType (T)) == T_TYPE_LONG);
}
@ -403,9 +401,31 @@ INLINE int IsTypeLong (const Type* T)
# define IsTypeLong(T) (GetRawType (GetUnderlyingType (T)) == T_TYPE_LONG)
#endif
#if defined(HAVE_INLINE)
INLINE int IsISOChar (const Type* T)
/* Return true if this is a narrow character type (without signed/unsigned) */
{
return (UnqualifiedType (T->C) == T_CHAR);
}
#else
# define IsISOChar(T) (UnqualifiedType ((T)->C) == T_CHAR)
#endif
#if defined(HAVE_INLINE)
INLINE int IsClassChar (const Type* T)
/* Return true if this is a narrow character type (including signed/unsigned).
** For now this is the same as IsRawTypeChar(T).
*/
{
return (GetRawType (T) == T_TYPE_CHAR);
}
#else
# define IsClassChar(T) (GetRawType (T) == T_TYPE_CHAR)
#endif
#if defined(HAVE_INLINE)
INLINE int IsRawTypeChar (const Type* T)
/* Return true if this is a character raw type */
/* Return true if this is a char raw type (including signed/unsigned) */
{
return (GetRawType (T) == T_TYPE_CHAR);
}

View File

@ -1169,7 +1169,7 @@ static void ParseTypeSpec (DeclSpec* D, long Default, TypeCode Qualifiers)
case TOK_CHAR:
NextToken ();
D->Type[0].C = GetDefaultChar();
D->Type[0].C = T_CHAR;
D->Type[1].C = T_END;
break;
@ -2195,7 +2195,7 @@ static unsigned ParseArrayInit (Type* T, int* Braces, int AllowFlexibleMembers)
long ElementCount = GetElementCount (T);
/* Special handling for a character array initialized by a literal */
if (IsRawTypeChar (ElementType) &&
if (IsClassChar (ElementType) &&
(CurTok.Tok == TOK_SCONST || CurTok.Tok == TOK_WCSCONST ||
(CurTok.Tok == TOK_LCURLY &&
(NextTok.Tok == TOK_SCONST || NextTok.Tok == TOK_WCSCONST)))) {

View File

@ -67,7 +67,7 @@ extern IntStack EnableRegVars; /* Enable register variables */
extern IntStack AllowRegVarAddr; /* Allow taking addresses of register vars */
extern IntStack RegVarsToCallStack; /* Save reg variables on call stack */
extern IntStack StaticLocals; /* Make local variables static */
extern IntStack SignedChars; /* Make characters signed by default */
extern IntStack SignedChars; /* Use 'signed char' as the underlying type of 'char' */
extern IntStack CheckStack; /* Generate stack overflow checks */
extern IntStack Optimize; /* Optimize flag */
extern IntStack CodeSizeFactor; /* Size factor for generated code */

View File

@ -731,7 +731,7 @@ static void OptRodataName (const char* Opt attribute ((unused)), const char* Arg
static void OptSignedChars (const char* Opt attribute ((unused)),
const char* Arg attribute ((unused)))
/* Make default characters signed */
/* Use 'signed char' as the underlying type of 'char' */
{
IS_Set (&SignedChars, 1);
}

View File

@ -783,8 +783,8 @@ static void StdFunc_strcmp (FuncDesc* F attribute ((unused)), ExprDesc* Expr)
int Offs;
/* Setup the argument type string */
Arg1Type[1].C = GetDefaultChar () | T_QUAL_CONST;
Arg2Type[1].C = GetDefaultChar () | T_QUAL_CONST;
Arg1Type[1].C = T_CHAR | T_QUAL_CONST;
Arg2Type[1].C = T_CHAR | T_QUAL_CONST;
/* Argument #1 */
ParseArg (&Arg1, Arg1Type);
@ -983,8 +983,8 @@ static void StdFunc_strcpy (FuncDesc* F attribute ((unused)), ExprDesc* Expr)
unsigned L1;
/* Setup the argument type string */
Arg1Type[1].C = GetDefaultChar ();
Arg2Type[1].C = GetDefaultChar () | T_QUAL_CONST;
Arg1Type[1].C = T_CHAR;
Arg2Type[1].C = T_CHAR | T_QUAL_CONST;
/* Argument #1 */
ParseArg (&Arg1, Arg1Type);
@ -1181,7 +1181,7 @@ static void StdFunc_strlen (FuncDesc* F attribute ((unused)), ExprDesc* Expr)
unsigned L;
/* Setup the argument type string */
ArgType[1].C = GetDefaultChar () | T_QUAL_CONST;
ArgType[1].C = T_CHAR | T_QUAL_CONST;
/* Evaluate the parameter */
hie1 (&Arg);

View File

@ -233,6 +233,12 @@ static void DoCompare (const Type* lhs, const Type* rhs, typecmp_t* Result)
}
/* 'char' is neither 'signed char' nor 'unsigned char' */
if ((IsISOChar (lhs) && !IsISOChar (rhs)) ||
(!IsISOChar (lhs) && IsISOChar (rhs))) {
SetResult (Result, TC_COMPATIBLE);
}
/* On indirection level zero, a qualifier or sign difference is
** accepted. The types are no longer equal, but compatible.
*/