1
0
mirror of https://github.com/cc65/cc65.git synced 2024-06-07 23:29:39 +00:00

Corrected and entailed comments and cleaned up code with type comparison.

This commit is contained in:
acqn 2022-10-13 13:45:22 +08:00
parent 01d2b809a1
commit cf3a0c4a30
2 changed files with 49 additions and 56 deletions

View File

@ -141,7 +141,7 @@ static void SetResult (typecmp_t* Result, typecmpcode_t Val)
static typecmp_t* CmpQuals (const Type* lhst, const Type* rhst, typecmp_t* Result)
/* Copare the types regarding thier qualifiers. Return the Result */
/* Compare the types regarding their qualifiers. Return via pointer *Result */
{
TypeCode LeftQual, RightQual;
@ -249,16 +249,10 @@ static void DoCompare (const Type* lhs, const Type* rhs, typecmp_t* Result)
/* Compare two types. Determine, where they differ */
while (lhs->C != T_END) {
/* Check if the end of the type string is reached */
if (rhs->C == T_END) {
/* End of comparison reached */
break;
}
while (lhs->C != T_END && rhs->C != T_END) {
/* Compare qualifiers */
if (CmpQuals (lhs, rhs, Result)->C == TC_INCOMPATIBLE) {
/* No need to compare further */
return;
}
@ -266,6 +260,22 @@ static void DoCompare (const Type* lhs, const Type* rhs, typecmp_t* Result)
LeftRank = (GetUnqualTypeCode (lhs) & T_MASK_RANK);
RightRank = (GetUnqualTypeCode (rhs) & T_MASK_RANK);
/* Bit-fields are considered compatible if they have the same
** signedness, bit-offset and bit-width.
*/
if (IsTypeBitField (lhs) || IsTypeBitField (rhs)) {
if (!IsTypeBitField (lhs) ||
!IsTypeBitField (rhs) ||
lhs->A.B.Offs != rhs->A.B.Offs ||
lhs->A.B.Width != rhs->A.B.Width) {
/* Incompatible */
goto Incompatible;
}
if (LeftRank != RightRank) {
SetResult (Result, TC_STRICT_COMPATIBLE);
}
}
/* If one side is a pointer and the other side is an array, both are
** compatible.
*/
@ -280,56 +290,35 @@ static void DoCompare (const Type* lhs, const Type* rhs, typecmp_t* Result)
}
}
/* Bit-fields are considered compatible if they have the same
** signedness, bit-offset and bit-width.
*/
if (IsTypeBitField (lhs) || IsTypeBitField (rhs)) {
if (!IsTypeBitField (lhs) ||
!IsTypeBitField (rhs) ||
lhs->A.B.Offs != rhs->A.B.Offs ||
lhs->A.B.Width != rhs->A.B.Width) {
SetResult (Result, TC_INCOMPATIBLE);
}
if (LeftRank != RightRank) {
SetResult (Result, TC_STRICT_COMPATIBLE);
}
}
/* If the ranks are different, the types are incompatible */
if (LeftRank != RightRank) {
SetResult (Result, TC_INCOMPATIBLE);
return;
goto Incompatible;
}
/* Enums must be handled specially */
if ((IsTypeEnum (lhs) || IsTypeEnum (rhs))) {
/* Compare the tag types */
Sym1 = IsTypeEnum (lhs) ? GetESUTagSym (lhs) : 0;
Sym2 = IsTypeEnum (rhs) ? GetESUTagSym (rhs) : 0;
Sym1 = GetESUTagSym (lhs);
Sym2 = GetESUTagSym (rhs);
/* For the two to be identical, they must be declared in the same
** scope and have the same name.
*/
if (Sym1 != Sym2) {
if (Sym1 == 0 || Sym2 == 0) {
/* Only one is an enum. So they can't be identical */
SetResult (Result, TC_STRICT_COMPATIBLE);
} else {
/* For the two to be identical, they must be in the same
** scope and have the same name.
} else if (Sym1->Owner != Sym2->Owner ||
strcmp (Sym1->Name, Sym2->Name) != 0) {
/* If any one of the two is incomplete, we can't guess
** their underlying types and have to assume that they
** be incompatible.
*/
if (Sym1->Owner != Sym2->Owner ||
strcmp (Sym1->Name, Sym2->Name) != 0) {
/* If any one of the two is incomplete, we can't guess
** their underlying types and have to assume that they
** be incompatible.
*/
if (SizeOf (lhs) == 0 || SizeOf (rhs) == 0) {
SetResult (Result, TC_INCOMPATIBLE);
return;
}
if (SizeOf (lhs) == 0 || SizeOf (rhs) == 0) {
goto Incompatible;
}
SetResult (Result, TC_STRICT_COMPATIBLE);
}
}
@ -383,15 +372,13 @@ static void DoCompare (const Type* lhs, const Type* rhs, typecmp_t* Result)
/* Check the remaining flags */
if ((F1->Flags & ~FD_IGNORE) != (F2->Flags & ~FD_IGNORE)) {
/* Flags differ */
SetResult (Result, TC_INCOMPATIBLE);
return;
goto Incompatible;
}
/* Compare the parameter lists */
if (EqualFuncParams (F1, F2) == 0) {
/* Parameter list is not identical */
SetResult (Result, TC_INCOMPATIBLE);
return;
goto Incompatible;
}
}
@ -406,8 +393,7 @@ static void DoCompare (const Type* lhs, const Type* rhs, typecmp_t* Result)
if (LeftCount != UNSPECIFIED &&
RightCount != UNSPECIFIED) {
/* Member count given but different */
SetResult (Result, TC_INCOMPATIBLE);
return;
goto Incompatible;
}
/* We take into account which side is more specified */
@ -436,8 +422,7 @@ static void DoCompare (const Type* lhs, const Type* rhs, typecmp_t* Result)
/* This shouldn't happen in the current code base, but
** we still handle this case to be future-proof.
*/
SetResult (Result, TC_INCOMPATIBLE);
return;
goto Incompatible;
}
}
@ -453,9 +438,11 @@ static void DoCompare (const Type* lhs, const Type* rhs, typecmp_t* Result)
/* Check if lhs and rhs both reached ends */
if (lhs->C == T_END && rhs->C == T_END) {
SetResult (Result, TC_IDENTICAL);
} else {
SetResult (Result, TC_INCOMPATIBLE);
return;
}
Incompatible:
SetResult (Result, TC_INCOMPATIBLE);
}
@ -483,7 +470,10 @@ typecmp_t TypeCmp (const Type* lhs, const Type* rhs)
void TypeCompatibilityDiagnostic (const Type* NewType, const Type* OldType, int IsError, const char* Msg)
/* Print error or warning message about type compatibility with proper type names */
/* Print error or warning message about type compatibility with proper type
** names. The format string shall contain two '%s' specifiers for the names of
** the two types.
*/
{
StrBuf NewTypeName = STATIC_STRBUF_INITIALIZER;
StrBuf OldTypeName = STATIC_STRBUF_INITIALIZER;

View File

@ -97,7 +97,10 @@ typecmp_t TypeCmp (const Type* lhs, const Type* rhs);
/* Compare two types and return the result */
void TypeCompatibilityDiagnostic (const Type* NewType, const Type* OldType, int IsError, const char* Msg);
/* Print error or warning message about type compatibility with proper type names */
/* Print error or warning message about type compatibility with proper type
** names. The format string shall contain two '%s' specifiers for the names of
** the two types.
*/