Fixed composition of prototypes and old-style function definitions with default promotions.
Fixed function parameter list comparison with empty ones.
This commit is contained in:
@@ -49,40 +49,6 @@
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
static int ParamsHaveDefaultPromotions (const FuncDesc* F)
|
|
||||||
/* Check if any of the parameters of function F has a default promotion. In
|
|
||||||
** this case, the function is not compatible with an empty parameter name list
|
|
||||||
** declaration.
|
|
||||||
*/
|
|
||||||
{
|
|
||||||
/* Get the symbol table */
|
|
||||||
const SymTable* Tab = F->SymTab;
|
|
||||||
|
|
||||||
/* Get the first parameter in the list */
|
|
||||||
const SymEntry* Sym = Tab->SymHead;
|
|
||||||
|
|
||||||
/* Walk over all parameters */
|
|
||||||
while (Sym && (Sym->Flags & SC_PARAM)) {
|
|
||||||
|
|
||||||
/* If this is an integer type, check if the promoted type is equal
|
|
||||||
** to the original type. If not, we have a default promotion.
|
|
||||||
*/
|
|
||||||
if (IsClassInt (Sym->Type)) {
|
|
||||||
if (IntPromotion (Sym->Type) != Sym->Type) {
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Get the pointer to the next param */
|
|
||||||
Sym = Sym->NextSym;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* No default promotions in the parameter list */
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
static int EqualFuncParams (const FuncDesc* F1, const FuncDesc* F2)
|
static int EqualFuncParams (const FuncDesc* F1, const FuncDesc* F2)
|
||||||
/* Compare two function symbol tables regarding function parameters. Return 1
|
/* Compare two function symbol tables regarding function parameters. Return 1
|
||||||
** if they are equal and 0 otherwise.
|
** if they are equal and 0 otherwise.
|
||||||
@@ -385,29 +351,16 @@ static void DoCompare (const Type* lhs, const Type* rhs, typecmp_t* Result)
|
|||||||
F1 = GetFuncDesc (lhs);
|
F1 = GetFuncDesc (lhs);
|
||||||
F2 = GetFuncDesc (rhs);
|
F2 = GetFuncDesc (rhs);
|
||||||
|
|
||||||
/* If one of both functions has an empty parameter list (which
|
/* If one of both function declarations has an empty parameter
|
||||||
** does also mean, it is not a function definition, because the
|
** list (which does also mean, it is not a function definition,
|
||||||
** flag is reset in this case), it is considered equal to any
|
** because the flag is reset in this case), it is ignored for
|
||||||
** other definition, provided that the other has no default
|
** parameter comparison and considered equal to the other one,
|
||||||
** promotions in the parameter list. If none of both parameter
|
** provided both have the same return type and other attributes.
|
||||||
** lists is empty, we have to check the parameter lists and
|
** If neither of both parameter lists is empty, we have to check
|
||||||
** other attributes.
|
** the parameter lists.
|
||||||
*/
|
*/
|
||||||
if (F1->Flags & FD_EMPTY) {
|
if ((F1->Flags & FD_EMPTY) == 0 &&
|
||||||
if ((F2->Flags & FD_EMPTY) == 0) {
|
(F2->Flags & FD_EMPTY) == 0) {
|
||||||
if (ParamsHaveDefaultPromotions (F2)) {
|
|
||||||
/* Flags differ */
|
|
||||||
SetResult (Result, TC_INCOMPATIBLE);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else if (F2->Flags & FD_EMPTY) {
|
|
||||||
if (ParamsHaveDefaultPromotions (F1)) {
|
|
||||||
/* Flags differ */
|
|
||||||
SetResult (Result, TC_INCOMPATIBLE);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
|
|
||||||
/* Check the remaining flags */
|
/* Check the remaining flags */
|
||||||
if ((F1->Flags & ~FD_IGNORE) != (F2->Flags & ~FD_IGNORE)) {
|
if ((F1->Flags & ~FD_IGNORE) != (F2->Flags & ~FD_IGNORE)) {
|
||||||
|
|||||||
@@ -352,18 +352,21 @@ void TypeCast (ExprDesc* Expr)
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
static void CompositeFuncParamList (const FuncDesc* F1, const FuncDesc* F2)
|
static void ComposeFuncParamList (const FuncDesc* F1, const FuncDesc* F2)
|
||||||
/* Composite two function symbol tables regarding function parameters */
|
/* Compose two function symbol tables regarding function parameters into F1 */
|
||||||
{
|
{
|
||||||
/* Get the symbol tables */
|
/* Get the symbol tables */
|
||||||
const SymTable* Tab1 = F1->SymTab;
|
const SymTable* Tab1 = F1->SymTab;
|
||||||
const SymTable* Tab2 = F2->SymTab;
|
const SymTable* Tab2 = F2->SymTab;
|
||||||
|
|
||||||
/* Composite the parameter lists */
|
/* Compose the parameter lists */
|
||||||
const SymEntry* Sym1 = Tab1->SymHead;
|
SymEntry* Sym1 = Tab1->SymHead;
|
||||||
const SymEntry* Sym2 = Tab2->SymHead;
|
SymEntry* Sym2 = Tab2->SymHead;
|
||||||
|
|
||||||
/* Composite the fields */
|
/* Sanity check */
|
||||||
|
CHECK ((F1->Flags & FD_EMPTY) == 0 && (F2->Flags & FD_EMPTY) == 0);
|
||||||
|
|
||||||
|
/* Compose the fields */
|
||||||
while (Sym1 && (Sym1->Flags & SC_PARAM) && Sym2 && (Sym2->Flags & SC_PARAM)) {
|
while (Sym1 && (Sym1->Flags & SC_PARAM) && Sym2 && (Sym2->Flags & SC_PARAM)) {
|
||||||
|
|
||||||
/* Get the symbol types */
|
/* Get the symbol types */
|
||||||
@@ -384,8 +387,19 @@ static void CompositeFuncParamList (const FuncDesc* F1, const FuncDesc* F2)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* When we compose two function parameter lists with any FD_OLDSTYLE
|
||||||
|
** flags set, we are either refining the declaration of the function
|
||||||
|
** with its definition seen, or determining the result type of a
|
||||||
|
** ternary operation. In either case, we can just replace the types
|
||||||
|
** with the promoted ones since the original types of the parameters
|
||||||
|
** only matters inside the function definition.
|
||||||
|
*/
|
||||||
|
if (Type1 != Sym1->Type) {
|
||||||
|
Sym1->Type = TypeDup (Type1);
|
||||||
|
}
|
||||||
|
|
||||||
/* Compose this field */
|
/* Compose this field */
|
||||||
TypeComposition (Type1, Type2);
|
TypeComposition (Sym1->Type, Type2);
|
||||||
|
|
||||||
/* Get the pointers to the next fields */
|
/* Get the pointers to the next fields */
|
||||||
Sym1 = Sym1->NextSym;
|
Sym1 = Sym1->NextSym;
|
||||||
@@ -404,7 +418,7 @@ void TypeComposition (Type* lhs, const Type* rhs)
|
|||||||
FuncDesc* F2;
|
FuncDesc* F2;
|
||||||
long LeftCount, RightCount;
|
long LeftCount, RightCount;
|
||||||
|
|
||||||
/* Composite two types */
|
/* Compose two types */
|
||||||
while (lhs->C != T_END) {
|
while (lhs->C != T_END) {
|
||||||
|
|
||||||
/* Check if the end of the type string is reached */
|
/* Check if the end of the type string is reached */
|
||||||
@@ -417,17 +431,15 @@ void TypeComposition (Type* lhs, const Type* rhs)
|
|||||||
|
|
||||||
/* Check for special type elements */
|
/* Check for special type elements */
|
||||||
if (IsTypeFunc (lhs)) {
|
if (IsTypeFunc (lhs)) {
|
||||||
/* Composite the function descriptors */
|
/* Compose the function descriptors */
|
||||||
F1 = GetFuncDesc (lhs);
|
F1 = GetFuncDesc (lhs);
|
||||||
F2 = GetFuncDesc (rhs);
|
F2 = GetFuncDesc (rhs);
|
||||||
|
|
||||||
/* If one of both functions has an empty parameter list (which
|
/* If F1 has an empty parameter list (which does also mean, it is
|
||||||
** does also mean, it is not a function definition, because the
|
** not a function definition, because the flag is reset in this
|
||||||
** flag is reset in this case), it is replaced by the other
|
** case), its declaration is replaced by the other declaration. If
|
||||||
** definition, provided that the other has no default
|
** neither of the parameter lists is empty, we have to compose them
|
||||||
** promotions in the parameter list. If none of both parameter
|
** as well as other attributes.
|
||||||
** lists is empty, we have to composite the parameter lists and
|
|
||||||
** other attributes.
|
|
||||||
*/
|
*/
|
||||||
if ((F1->Flags & FD_EMPTY) == FD_EMPTY) {
|
if ((F1->Flags & FD_EMPTY) == FD_EMPTY) {
|
||||||
if ((F2->Flags & FD_EMPTY) == 0) {
|
if ((F2->Flags & FD_EMPTY) == 0) {
|
||||||
@@ -436,8 +448,12 @@ void TypeComposition (Type* lhs, const Type* rhs)
|
|||||||
F1->Flags = F2->Flags;
|
F1->Flags = F2->Flags;
|
||||||
}
|
}
|
||||||
} else if ((F2->Flags & FD_EMPTY) == 0) {
|
} else if ((F2->Flags & FD_EMPTY) == 0) {
|
||||||
/* Composite the parameter lists */
|
/* Compose the parameter lists */
|
||||||
CompositeFuncParamList (F1, F2);
|
ComposeFuncParamList (F1, F2);
|
||||||
|
/* Prefer non-old-style */
|
||||||
|
if ((F2->Flags & FD_OLDSTYLE) == 0) {
|
||||||
|
F1->Flags &= ~FD_OLDSTYLE;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else if (IsTypeArray (lhs)) {
|
} else if (IsTypeArray (lhs)) {
|
||||||
/* Check member count */
|
/* Check member count */
|
||||||
|
|||||||
Reference in New Issue
Block a user