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 "<type>" for unknown basic types.
 */
 {
     switch (GetRawTypeRank (T)) {
@@ -1273,7 +1310,7 @@ const char* GetBasicTypeName (const Type* T)
             }
         }
     }
-    return "type";
+    return "<type>";
 }
 
 
@@ -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 "<type>" 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 */