From 1dccd1333bebca6d1d64e8b5fbf6b83193ac5509 Mon Sep 17 00:00:00 2001 From: acqn Date: Wed, 12 Oct 2022 13:10:17 +0800 Subject: [PATCH] Added more type utility functions. Changed result of GetBasicTypeName() for unknown types from "type" to "". --- src/cc65/datatype.c | 43 ++++++++++++++++++++++++++++++++++++++++--- src/cc65/datatype.h | 25 ++++++++++++++++++++++++- src/cc65/expr.c | 12 ++++++------ src/cc65/symtab.c | 11 ++++------- 4 files changed, 74 insertions(+), 17 deletions(-) diff --git a/src/cc65/datatype.c b/src/cc65/datatype.c index 37fe54023..cb013ca21 100644 --- a/src/cc65/datatype.c +++ b/src/cc65/datatype.c @@ -816,6 +816,14 @@ const Type* GetStructReplacementType (const Type* SType) +const Type* GetBitFieldDeclType (const Type* Type) +/* Get the original integer type used to declare the bit-field */ +{ + return Type + 1; +} + + + const Type* GetBitFieldChunkType (const Type* Type) /* Get the type needed to operate on the byte chunk containing the bit-field */ { @@ -864,6 +872,16 @@ int IsTypeFragBitField (const Type* T) +#if !defined(HAVE_INLINE) +int IsTypeFuncLike (const Type* T) +/* Return true if this is a function or a function pointer */ +{ + return IsTypeFunc (T) || IsTypeFuncPtr (T); +} +#endif + + + int IsObjectType (const Type* T) /* Return true if this is a fully described object type */ { @@ -923,6 +941,14 @@ int IsAggregateType (const Type* T) +int IsDerivedDeclaratorType (const Type* T) +/* Return true if this is an array, function or pointer type */ +{ + return IsTypeArray (T) || IsTypeFunc (T) || IsTypePtr (T); +} + + + int IsRelationType (const Type* T) /* Return true if this is an arithmetic, array or pointer type */ { @@ -957,6 +983,17 @@ int IsIncompleteESUType (const Type* T) +int IsPassByRefType (const Type* T) +/* Return true if this is a large struct/union type that doesn't fit in the +** primary. This returns false for the void value extension type since it is +** not passable at all. +*/ +{ + return IsClassStruct (T) && GetStructReplacementType (T) == T; +} + + + int IsEmptiableObjectType (const Type* T) /* Return true if this is a struct/union/void type that can have zero size */ { @@ -1223,7 +1260,7 @@ void SetESUTagSym (Type* T, struct SymEntry* S) const char* GetBasicTypeName (const Type* T) /* Return a const name string of the basic type. -** Return "type" for unknown basic types. +** Return "" for unknown basic types. */ { switch (GetRawTypeRank (T)) { @@ -1273,7 +1310,7 @@ const char* GetBasicTypeName (const Type* T) } } } - return "type"; + return ""; } @@ -1433,7 +1470,7 @@ static struct StrBuf* GetFullTypeNameWestEast (struct StrBuf* West, struct StrBu if (!IsTypeBitField (T)) { SB_AppendStr (&Buf, GetTagSymName (T)); } else { - SB_AppendStr (&Buf, GetBasicTypeName (T + 1)); + SB_AppendStr (&Buf, GetBasicTypeName (GetBitFieldDeclType (T))); } if (!SB_IsEmpty (West)) { diff --git a/src/cc65/datatype.h b/src/cc65/datatype.h index eebd3abd8..06bb9168b 100644 --- a/src/cc65/datatype.h +++ b/src/cc65/datatype.h @@ -482,6 +482,9 @@ const Type* GetUnderlyingType (const Type* Type); const Type* GetStructReplacementType (const Type* SType); /* Get a replacement type for passing a struct/union by value in the primary */ +const Type* GetBitFieldDeclType (const Type* Type); +/* Get the original integer type used to declare the bit-field */ + const Type* GetBitFieldChunkType (const Type* Type); /* Get the type needed to operate on the byte chunk containing the bit-field */ @@ -690,6 +693,17 @@ INLINE int IsTypeFuncPtr (const Type* T) # define IsTypeFuncPtr(T) (IsTypePtr (T) && IsTypeFunc (T+1)) #endif +#if defined(HAVE_INLINE) +INLINE int IsTypeFuncLike (const Type* T) +/* Return true if this is a function or a function pointer */ +{ + return IsTypeFunc (T) || IsTypeFuncPtr (T); +} +#else +int IsTypeFuncLike (const Type* T); +/* Return true if this is a function or a function pointer */ +#endif + #if defined(HAVE_INLINE) INLINE int IsClassInt (const Type* T) /* Return true if this is an integer type */ @@ -761,6 +775,9 @@ int IsDerivedType (const Type* T); int IsAggregateType (const Type* T); /* Return true if this is an array or struct type */ +int IsDerivedDeclaratorType (const Type* T); +/* Return true if this is an array, function or pointer type */ + int IsRelationType (const Type* T); /* Return true if this is an arithmetic, array or pointer type */ @@ -773,6 +790,12 @@ int IsESUType (const Type* T); int IsIncompleteESUType (const Type* T); /* Return true if this is an incomplete ESU type */ +int IsPassByRefType (const Type* T); +/* Return true if this is a large struct/union type that doesn't fit in the +** primary. This returns false for the void value extension type since it is +** not passable at all. +*/ + int IsEmptiableObjectType (const Type* T); /* Return true if this is a struct/union/void type that can have zero size */ @@ -1024,7 +1047,7 @@ void SetESUTagSym (Type* T, struct SymEntry* S); const char* GetBasicTypeName (const Type* T); /* Return a const name string of the basic type. -** Return "type" for unknown basic types. +** Return "" for unknown basic types. */ const char* GetFullTypeName (const Type* T); diff --git a/src/cc65/expr.c b/src/cc65/expr.c index aef0679d4..4a8fd6eab 100644 --- a/src/cc65/expr.c +++ b/src/cc65/expr.c @@ -1619,9 +1619,9 @@ static void hie11 (ExprDesc *Expr) break; case TOK_LPAREN: - /* Function call. */ - if (!IsTypeFunc (Expr->Type) && !IsTypeFuncPtr (Expr->Type)) { - /* Not a function */ + /* Function call */ + if (!IsTypeFuncLike (Expr->Type)) { + /* Not a function or function pointer */ Error ("Illegal function call"); /* Force the type to be a implicitly defined function, one ** returning an int and taking any number of arguments. @@ -2035,7 +2035,7 @@ void hie10 (ExprDesc* Expr) ** of dereference operators is legal, since the result will ** always be converted to "pointer to function". */ - if (IsTypeFuncPtr (Expr->Type) || IsTypeFunc (Expr->Type)) { + if (IsTypeFuncLike (Expr->Type)) { /* Expression not storable */ ED_MarkExprAsRVal (Expr); } else { @@ -3216,7 +3216,7 @@ static void parsesub (ExprDesc* Expr) Expr2.Flags |= Expr->Flags & E_MASK_KEEP_SUBEXPR; /* lhs cannot be function or pointer to function */ - if (IsTypeFunc (Expr->Type) || IsTypeFuncPtr (Expr->Type)) { + if (IsTypeFuncLike (Expr->Type)) { Error ("Invalid left operand for binary operator '-'"); /* Make it pointer to char to avoid further errors */ Expr->Type = type_uchar; @@ -3241,7 +3241,7 @@ static void parsesub (ExprDesc* Expr) MarkedExprWithCheck (hie9, &Expr2); /* rhs cannot be function or pointer to function */ - if (IsTypeFunc (Expr2.Type) || IsTypeFuncPtr (Expr2.Type)) { + if (IsTypeFuncLike (Expr2.Type)) { Error ("Invalid right operand for binary operator '-'"); /* Make it pointer to char to avoid further errors */ Expr2.Type = type_uchar; diff --git a/src/cc65/symtab.c b/src/cc65/symtab.c index 951ed9e5e..b54cba2db 100644 --- a/src/cc65/symtab.c +++ b/src/cc65/symtab.c @@ -1009,7 +1009,6 @@ SymEntry* AddBitField (const char* Name, const Type* T, unsigned Offs, Entry = NewSymEntry (Name, SC_BITFIELD); /* Set the symbol attributes. Bit-fields are always integral types. */ - Entry->Type = NewBitFieldOf (T, BitOffs, BitWidth); Entry->V.Offs = Offs; if (!SignednessSpecified) { @@ -1020,12 +1019,10 @@ SymEntry* AddBitField (const char* Name, const Type* T, unsigned Offs, ** is controlled by `--signed-chars`. In bit-fields, however, we perform the same ** `char -> unsigned char` adjustment that is performed with other integral types. */ - CHECK ((Entry->Type->C & T_MASK_SIGN) == T_SIGN_SIGNED || - IsRankChar (Entry->Type)); - Entry->Type[0].C &= ~T_MASK_SIGN; - Entry->Type[0].C |= T_SIGN_UNSIGNED; - Entry->Type[1].C &= ~T_MASK_SIGN; - Entry->Type[1].C |= T_SIGN_UNSIGNED; + CHECK (IsSignSigned (T) || IsRankChar (T)); + Entry->Type = NewBitFieldOf (GetUnsignedType (T), BitOffs, BitWidth); + } else { + Entry->Type = NewBitFieldOf (T, BitOffs, BitWidth); } /* Add the entry to the symbol table */