1 /*****************************************************************************/
5 /* Type compare function for the cc65 C compiler */
9 /* (C) 1998-2000 Ullrich von Bassewitz */
11 /* D-70597 Stuttgart */
12 /* EMail: uz@musoftware.de */
15 /* This software is provided 'as-is', without any expressed or implied */
16 /* warranty. In no event will the authors be held liable for any damages */
17 /* arising from the use of this software. */
19 /* Permission is granted to anyone to use this software for any purpose, */
20 /* including commercial applications, and to alter it and redistribute it */
21 /* freely, subject to the following restrictions: */
23 /* 1. The origin of this software must not be misrepresented; you must not */
24 /* claim that you wrote the original software. If you use this software */
25 /* in a product, an acknowledgment in the product documentation would be */
26 /* appreciated but is not required. */
27 /* 2. Altered source versions must be plainly marked as such, and must not */
28 /* be misrepresented as being the original software. */
29 /* 3. This notice may not be removed or altered from any source */
32 /*****************************************************************************/
42 /*****************************************************************************/
44 /*****************************************************************************/
48 static void SetResult (typecmp_t* Result, typecmp_t Val)
49 /* Set a new result value if it is less than the existing one */
58 static int EqualFuncParams (SymTable* Tab1, SymTable* Tab2)
59 /* Compare two function symbol tables regarding function parameters. Return 1
60 * if they are equal and 0 otherwise.
63 /* Compare the parameter lists */
64 SymEntry* Sym1 = Tab1->SymHead;
65 SymEntry* Sym2 = Tab2->SymHead;
67 /* Compare the fields */
68 while (Sym1 && (Sym1->Flags & SC_PARAM) && Sym2 && (Sym2->Flags & SC_PARAM)) {
70 /* Compare this field */
71 if (TypeCmp (Sym1->Type, Sym2->Type) < TC_EQUAL) {
72 /* Field types not equal */
76 /* Get the pointers to the next fields */
81 /* Check both pointers against NULL or a non parameter to compare the
84 return (Sym1 == 0 || (Sym1->Flags & SC_PARAM) == 0) &&
85 (Sym2 == 0 || (Sym2->Flags & SC_PARAM) == 0);
90 static int EqualSymTables (SymTable* Tab1, SymTable* Tab2)
91 /* Compare two symbol tables. Return 1 if they are equal and 0 otherwise */
93 /* Compare the parameter lists */
94 SymEntry* Sym1 = Tab1->SymHead;
95 SymEntry* Sym2 = Tab2->SymHead;
97 /* Compare the fields */
98 while (Sym1 && Sym2) {
100 /* Compare this field */
101 if (TypeCmp (Sym1->Type, Sym2->Type) < TC_EQUAL) {
102 /* Field types not equal */
106 /* Get the pointers to the next fields */
107 Sym1 = Sym1->NextSym;
108 Sym2 = Sym2->NextSym;
111 /* Check both pointers against NULL to compare the field count */
112 return (Sym1 == 0 && Sym2 == 0);
117 static void DoCompare (const type* lhs, const type* rhs, typecmp_t* Result)
118 /* Recursively compare two types. */
120 unsigned Indirections;
121 unsigned ElementCount;
131 /* Initialize stuff */
135 /* Compare two types. Determine, where they differ */
136 while (*lhs != T_END) {
138 type LeftType, RightType;
139 type LeftSign, RightSign;
140 type LeftQual, RightQual;
141 unsigned LeftCount, RightCount;
143 /* Check if the end of the type string is reached */
145 /* End of comparison reached */
149 /* Get the raw left and right types, signs and qualifiers */
150 LeftType = GetType (lhs);
151 RightType = GetType (rhs);
152 LeftSign = GetSignedness (lhs);
153 RightSign = GetSignedness (rhs);
154 LeftQual = GetQualifier (lhs);
155 RightQual = GetQualifier (rhs);
157 /* If the left type is a pointer and the right is an array, both
160 if (LeftType == T_TYPE_PTR && RightType == T_TYPE_ARRAY) {
161 RightType = T_TYPE_PTR;
165 /* If the raw types are not identical, the types are incompatible */
166 if (LeftType != RightType) {
167 SetResult (Result, TC_INCOMPATIBLE);
171 /* On indirection level zero, a qualifier or sign difference is
172 * accepted. The types are no longer equal, but compatible.
174 if (LeftSign != RightSign) {
175 if (ElementCount == 0) {
176 SetResult (Result, TC_SIGN_DIFF);
178 SetResult (Result, TC_INCOMPATIBLE);
182 if (LeftQual != RightQual) {
183 /* On the first indirection level, different qualifiers mean
184 * that the types are still compatible. On the second level,
185 * this is a (maybe minor) error, so we create a special
186 * return code, since a qualifier is dropped from a pointer.
187 * Starting from the next level, the types are incompatible
188 * if the qualifiers differ.
190 switch (Indirections) {
193 SetResult (Result, TC_STRICT_COMPATIBLE);
197 /* A non const value on the right is compatible to a
198 * const one to the left, same for volatile.
200 if ((LeftQual & T_QUAL_CONST) < (RightQual & T_QUAL_CONST) ||
201 (LeftQual & T_QUAL_VOLATILE) < (RightQual & T_QUAL_VOLATILE)) {
202 SetResult (Result, TC_QUAL_DIFF);
204 SetResult (Result, TC_STRICT_COMPATIBLE);
209 SetResult (Result, TC_INCOMPATIBLE);
214 /* Check for special type elements */
222 /* Compare the function descriptors */
223 F1 = DecodePtr (lhs+1);
224 F2 = DecodePtr (rhs+1);
226 /* If one of the functions is implicitly declared, both
227 * functions are considered equal. If one of the functions is
228 * old style, and the other is empty, the functions are
231 if ((F1->Flags & FD_IMPLICIT) != 0 || (F2->Flags & FD_IMPLICIT) != 0) {
233 } else if ((F1->Flags & FD_OLDSTYLE) != 0 && (F2->Flags & FD_EMPTY) != 0) {
235 } else if ((F1->Flags & FD_EMPTY) != 0 && (F2->Flags & FD_OLDSTYLE) != 0) {
243 /* Check the remaining flags */
244 if ((F1->Flags & ~FD_IGNORE) != (F2->Flags & ~FD_IGNORE)) {
246 SetResult (Result, TC_INCOMPATIBLE);
250 /* Compare the parameter lists */
251 if (EqualFuncParams (F1->SymTab, F2->SymTab) == 0 ||
252 EqualSymTables (F1->TagTab, F2->TagTab) == 0) {
253 /* One of the tables is not identical */
254 SetResult (Result, TC_INCOMPATIBLE);
259 /* Skip the FuncDesc pointers to compare the return type */
265 /* Check member count */
266 LeftCount = Decode (lhs+1);
267 RightCount = Decode (rhs+1);
268 if (LeftCount != 0 && RightCount != 0 && LeftCount != RightCount) {
269 /* Member count given but different */
270 SetResult (Result, TC_INCOMPATIBLE);
279 /* Compare the fields recursively. To do that, we fetch the
280 * pointer to the struct definition from the type, and compare
283 Sym1 = DecodePtr (lhs+1);
284 Sym2 = DecodePtr (rhs+1);
286 /* Get the field tables from the struct entry */
287 Tab1 = Sym1->V.S.SymTab;
288 Tab2 = Sym2->V.S.SymTab;
290 /* One or both structs may be forward definitions. In this case,
291 * the symbol tables are both non existant. Assume that the
292 * structs are equal in this case.
294 if (Tab1 != 0 && Tab2 != 0) {
296 if (EqualSymTables (Tab1, Tab2) == 0) {
297 /* Field lists are not equal */
298 SetResult (Result, TC_INCOMPATIBLE);
304 /* Structs are equal */
310 /* Next type string element */
316 /* Check if end of rhs reached */
318 SetResult (Result, TC_EQUAL);
320 SetResult (Result, TC_INCOMPATIBLE);
326 typecmp_t TypeCmp (const type* lhs, const type* rhs)
327 /* Compare two types and return the result */
329 /* Assume the types are identical */
330 typecmp_t Result = TC_IDENTICAL;
333 printf ("Left : "); PrintRawType (stdout, lhs);
334 printf ("Right: "); PrintRawType (stdout, rhs);
337 /* Recursively compare the types if they aren't identical */
339 DoCompare (lhs, rhs, &Result);
342 /* Return the result */