@@ -52,7 +52,7 @@
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
static struct Segments* CurrentFunctionSegment;
|
static struct SegContext* CurrentFunctionSegment;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -62,7 +62,7 @@ static struct Segments* CurrentFunctionSegment;
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
void UseLabelPoolFromSegments (struct Segments* Seg)
|
void UseLabelPoolFromSegments (struct SegContext* Seg)
|
||||||
/* Use the info in segments for generating new label numbers */
|
/* Use the info in segments for generating new label numbers */
|
||||||
{
|
{
|
||||||
CurrentFunctionSegment = Seg;
|
CurrentFunctionSegment = Seg;
|
||||||
|
|||||||
@@ -44,7 +44,7 @@
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
struct Segments;
|
struct SegContext;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -54,7 +54,7 @@ struct Segments;
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
void UseLabelPoolFromSegments (struct Segments* Seg);
|
void UseLabelPoolFromSegments (struct SegContext* Seg);
|
||||||
/* Use the info in segments for generating new label numbers */
|
/* Use the info in segments for generating new label numbers */
|
||||||
|
|
||||||
unsigned GetLocalLabel (void);
|
unsigned GetLocalLabel (void);
|
||||||
|
|||||||
@@ -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)
|
const Type* GetBitFieldChunkType (const Type* Type)
|
||||||
/* Get the type needed to operate on the byte chunk containing the bit-field */
|
/* 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)
|
int IsObjectType (const Type* T)
|
||||||
/* Return true if this is a fully described object type */
|
/* 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)
|
int IsRelationType (const Type* T)
|
||||||
/* Return true if this is an arithmetic, array or pointer type */
|
/* 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)
|
int IsEmptiableObjectType (const Type* T)
|
||||||
/* Return true if this is a struct/union/void type that can have zero size */
|
/* 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)
|
const char* GetBasicTypeName (const Type* T)
|
||||||
/* Return a const name string of the basic type.
|
/* Return a const name string of the basic type.
|
||||||
** Return "type" for unknown basic types.
|
** Return "<type>" for unknown basic types.
|
||||||
*/
|
*/
|
||||||
{
|
{
|
||||||
switch (GetRawTypeRank (T)) {
|
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)) {
|
if (!IsTypeBitField (T)) {
|
||||||
SB_AppendStr (&Buf, GetTagSymName (T));
|
SB_AppendStr (&Buf, GetTagSymName (T));
|
||||||
} else {
|
} else {
|
||||||
SB_AppendStr (&Buf, GetBasicTypeName (T + 1));
|
SB_AppendStr (&Buf, GetBasicTypeName (GetBitFieldDeclType (T)));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!SB_IsEmpty (West)) {
|
if (!SB_IsEmpty (West)) {
|
||||||
|
|||||||
@@ -482,6 +482,9 @@ const Type* GetUnderlyingType (const Type* Type);
|
|||||||
const Type* GetStructReplacementType (const Type* SType);
|
const Type* GetStructReplacementType (const Type* SType);
|
||||||
/* Get a replacement type for passing a struct/union by value in the primary */
|
/* 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);
|
const Type* GetBitFieldChunkType (const Type* Type);
|
||||||
/* Get the type needed to operate on the byte chunk containing the bit-field */
|
/* 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))
|
# define IsTypeFuncPtr(T) (IsTypePtr (T) && IsTypeFunc (T+1))
|
||||||
#endif
|
#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)
|
#if defined(HAVE_INLINE)
|
||||||
INLINE int IsClassInt (const Type* T)
|
INLINE int IsClassInt (const Type* T)
|
||||||
/* Return true if this is an integer type */
|
/* Return true if this is an integer type */
|
||||||
@@ -761,6 +775,9 @@ int IsDerivedType (const Type* T);
|
|||||||
int IsAggregateType (const Type* T);
|
int IsAggregateType (const Type* T);
|
||||||
/* Return true if this is an array or struct type */
|
/* 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);
|
int IsRelationType (const Type* T);
|
||||||
/* Return true if this is an arithmetic, array or pointer type */
|
/* 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);
|
int IsIncompleteESUType (const Type* T);
|
||||||
/* Return true if this is an incomplete ESU type */
|
/* 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);
|
int IsEmptiableObjectType (const Type* T);
|
||||||
/* Return true if this is a struct/union/void type that can have zero size */
|
/* 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);
|
const char* GetBasicTypeName (const Type* T);
|
||||||
/* Return a const name string of the basic type.
|
/* 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);
|
const char* GetFullTypeName (const Type* T);
|
||||||
|
|||||||
@@ -1619,9 +1619,9 @@ static void hie11 (ExprDesc *Expr)
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case TOK_LPAREN:
|
case TOK_LPAREN:
|
||||||
/* Function call. */
|
/* Function call */
|
||||||
if (!IsTypeFunc (Expr->Type) && !IsTypeFuncPtr (Expr->Type)) {
|
if (!IsTypeFuncLike (Expr->Type)) {
|
||||||
/* Not a function */
|
/* Not a function or function pointer */
|
||||||
Error ("Illegal function call");
|
Error ("Illegal function call");
|
||||||
/* Force the type to be a implicitly defined function, one
|
/* Force the type to be a implicitly defined function, one
|
||||||
** returning an int and taking any number of arguments.
|
** 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
|
** of dereference operators is legal, since the result will
|
||||||
** always be converted to "pointer to function".
|
** always be converted to "pointer to function".
|
||||||
*/
|
*/
|
||||||
if (IsTypeFuncPtr (Expr->Type) || IsTypeFunc (Expr->Type)) {
|
if (IsTypeFuncLike (Expr->Type)) {
|
||||||
/* Expression not storable */
|
/* Expression not storable */
|
||||||
ED_MarkExprAsRVal (Expr);
|
ED_MarkExprAsRVal (Expr);
|
||||||
} else {
|
} else {
|
||||||
@@ -3216,7 +3216,7 @@ static void parsesub (ExprDesc* Expr)
|
|||||||
Expr2.Flags |= Expr->Flags & E_MASK_KEEP_SUBEXPR;
|
Expr2.Flags |= Expr->Flags & E_MASK_KEEP_SUBEXPR;
|
||||||
|
|
||||||
/* lhs cannot be function or pointer to function */
|
/* 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 '-'");
|
Error ("Invalid left operand for binary operator '-'");
|
||||||
/* Make it pointer to char to avoid further errors */
|
/* Make it pointer to char to avoid further errors */
|
||||||
Expr->Type = type_uchar;
|
Expr->Type = type_uchar;
|
||||||
@@ -3241,7 +3241,7 @@ static void parsesub (ExprDesc* Expr)
|
|||||||
MarkedExprWithCheck (hie9, &Expr2);
|
MarkedExprWithCheck (hie9, &Expr2);
|
||||||
|
|
||||||
/* rhs cannot be function or pointer to function */
|
/* 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 '-'");
|
Error ("Invalid right operand for binary operator '-'");
|
||||||
/* Make it pointer to char to avoid further errors */
|
/* Make it pointer to char to avoid further errors */
|
||||||
Expr2.Type = type_uchar;
|
Expr2.Type = type_uchar;
|
||||||
|
|||||||
@@ -547,7 +547,7 @@ void NewFunc (SymEntry* Func, FuncDesc* D)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Allocate code and data segments for this function */
|
/* Allocate code and data segments for this function */
|
||||||
Func->V.F.Seg = PushSegments (Func);
|
Func->V.F.Seg = PushSegContext (Func);
|
||||||
|
|
||||||
/* Use the info in the segments for generating new local labels */
|
/* Use the info in the segments for generating new local labels */
|
||||||
UseLabelPoolFromSegments (Func->V.F.Seg);
|
UseLabelPoolFromSegments (Func->V.F.Seg);
|
||||||
@@ -696,7 +696,7 @@ void NewFunc (SymEntry* Func, FuncDesc* D)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Switch back to the old segments */
|
/* Switch back to the old segments */
|
||||||
PopSegments ();
|
PopSegContext ();
|
||||||
|
|
||||||
/* Reset the current function pointer */
|
/* Reset the current function pointer */
|
||||||
FreeFunction (CurrentFunc);
|
FreeFunction (CurrentFunc);
|
||||||
|
|||||||
@@ -69,11 +69,11 @@ typedef struct {
|
|||||||
} SegAddrSize_t;
|
} SegAddrSize_t;
|
||||||
|
|
||||||
|
|
||||||
/* Pointer to the current segment list. Output goes here. */
|
/* Pointer to the current segment context. Output goes here. */
|
||||||
Segments* CS = 0;
|
SegContext* CS = 0;
|
||||||
|
|
||||||
/* Pointer to the global segment list */
|
/* Pointer to the global segment context */
|
||||||
Segments* GS = 0;
|
SegContext* GS = 0;
|
||||||
|
|
||||||
/* Actual names for the segments */
|
/* Actual names for the segments */
|
||||||
static StrStack SegmentNames[SEG_COUNT];
|
static StrStack SegmentNames[SEG_COUNT];
|
||||||
@@ -86,12 +86,12 @@ static Collection SegmentAddrSizes;
|
|||||||
** maximum stack depth is 2, so there is not really a need for a better
|
** maximum stack depth is 2, so there is not really a need for a better
|
||||||
** implementation.
|
** implementation.
|
||||||
*/
|
*/
|
||||||
static Collection SegmentStack = STATIC_COLLECTION_INITIALIZER;
|
static Collection SegContextStack = STATIC_COLLECTION_INITIALIZER;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
/* Code */
|
/* Segment name and address size */
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
@@ -226,11 +226,17 @@ const char* GetSegName (segment_t Seg)
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
static Segments* NewSegments (SymEntry* Func)
|
/*****************************************************************************/
|
||||||
/* Initialize a Segments structure (set all fields to NULL) */
|
/* Segment context */
|
||||||
|
/*****************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
static SegContext* NewSegContext (SymEntry* Func)
|
||||||
|
/* Initialize a SegContext structure (set all fields to NULL) */
|
||||||
{
|
{
|
||||||
/* Allocate memory */
|
/* Allocate memory */
|
||||||
Segments* S = xmalloc (sizeof (Segments));
|
SegContext* S = xmalloc (sizeof (SegContext));
|
||||||
|
|
||||||
/* Initialize the fields */
|
/* Initialize the fields */
|
||||||
S->Text = NewTextSeg (Func);
|
S->Text = NewTextSeg (Func);
|
||||||
@@ -248,14 +254,14 @@ static Segments* NewSegments (SymEntry* Func)
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
Segments* PushSegments (SymEntry* Func)
|
SegContext* PushSegContext (SymEntry* Func)
|
||||||
/* Make the new segment list current but remember the old one */
|
/* Make the new segment context current but remember the old one */
|
||||||
{
|
{
|
||||||
/* Push the current pointer onto the stack */
|
/* Push the current pointer onto the stack */
|
||||||
CollAppend (&SegmentStack, CS);
|
CollAppend (&SegContextStack, CS);
|
||||||
|
|
||||||
/* Create a new Segments structure */
|
/* Create a new SegContext structure */
|
||||||
CS = NewSegments (Func);
|
CS = NewSegContext (Func);
|
||||||
|
|
||||||
/* Return the new struct */
|
/* Return the new struct */
|
||||||
return CS;
|
return CS;
|
||||||
@@ -263,14 +269,14 @@ Segments* PushSegments (SymEntry* Func)
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
void PopSegments (void)
|
void PopSegContext (void)
|
||||||
/* Pop the old segment list (make it current) */
|
/* Pop the old segment context (make it current) */
|
||||||
{
|
{
|
||||||
/* Must have something on the stack */
|
/* Must have something on the stack */
|
||||||
PRECONDITION (CollCount (&SegmentStack) > 0);
|
PRECONDITION (CollCount (&SegContextStack) > 0);
|
||||||
|
|
||||||
/* Pop the last segment and set it as current */
|
/* Pop the last segment and set it as current */
|
||||||
CS = CollPop (&SegmentStack);
|
CS = CollPop (&SegContextStack);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -278,13 +284,13 @@ void PopSegments (void)
|
|||||||
void CreateGlobalSegments (void)
|
void CreateGlobalSegments (void)
|
||||||
/* Create the global segments and remember them in GS */
|
/* Create the global segments and remember them in GS */
|
||||||
{
|
{
|
||||||
GS = PushSegments (0);
|
GS = PushSegContext (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void UseDataSeg (segment_t DSeg)
|
void UseDataSeg (segment_t DSeg)
|
||||||
/* For the current segment list, use the data segment DSeg */
|
/* For the current segment context, use the data segment DSeg */
|
||||||
{
|
{
|
||||||
/* Check the input */
|
/* Check the input */
|
||||||
PRECONDITION (CS && DSeg != SEG_CODE);
|
PRECONDITION (CS && DSeg != SEG_CODE);
|
||||||
@@ -372,7 +378,7 @@ void RemoveGlobalCode (void)
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
void OutputSegments (const Segments* S)
|
void OutputSegments (const SegContext* S)
|
||||||
/* Output the given segments to the output file */
|
/* Output the given segments to the output file */
|
||||||
{
|
{
|
||||||
/* Output the function prologue if the segments came from a function */
|
/* Output the function prologue if the segments came from a function */
|
||||||
|
|||||||
@@ -78,8 +78,8 @@ typedef enum segment_t {
|
|||||||
} segment_t;
|
} segment_t;
|
||||||
|
|
||||||
/* A list of all segments used when generating code */
|
/* A list of all segments used when generating code */
|
||||||
typedef struct Segments Segments;
|
typedef struct SegContext SegContext;
|
||||||
struct Segments {
|
struct SegContext {
|
||||||
struct TextSeg* Text; /* Text segment */
|
struct TextSeg* Text; /* Text segment */
|
||||||
struct CodeSeg* Code; /* Code segment */
|
struct CodeSeg* Code; /* Code segment */
|
||||||
struct DataSeg* Data; /* Data segment */
|
struct DataSeg* Data; /* Data segment */
|
||||||
@@ -90,11 +90,11 @@ struct Segments {
|
|||||||
unsigned NextDataLabel; /* Number to generate unique data labels */
|
unsigned NextDataLabel; /* Number to generate unique data labels */
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Pointer to the current segment list. Output goes here. */
|
/* Pointer to the current segment context. Output goes here. */
|
||||||
extern Segments* CS;
|
extern SegContext* CS;
|
||||||
|
|
||||||
/* Pointer to the global segment list */
|
/* Pointer to the global segment context */
|
||||||
extern Segments* GS;
|
extern SegContext* GS;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -132,17 +132,17 @@ void PopSegName (segment_t Seg);
|
|||||||
const char* GetSegName (segment_t Seg);
|
const char* GetSegName (segment_t Seg);
|
||||||
/* Get the name of the given segment */
|
/* Get the name of the given segment */
|
||||||
|
|
||||||
Segments* PushSegments (struct SymEntry* Func);
|
SegContext* PushSegContext (struct SymEntry* Func);
|
||||||
/* Make the new segment list current but remember the old one */
|
/* Make the new segment context current but remember the old one */
|
||||||
|
|
||||||
void PopSegments (void);
|
void PopSegContext (void);
|
||||||
/* Pop the old segment list (make it current) */
|
/* Pop the old segment context (make it current) */
|
||||||
|
|
||||||
void CreateGlobalSegments (void);
|
void CreateGlobalSegments (void);
|
||||||
/* Create the global segments and remember them in GS */
|
/* Create the global segments and remember them in GS */
|
||||||
|
|
||||||
void UseDataSeg (segment_t DSeg);
|
void UseDataSeg (segment_t DSeg);
|
||||||
/* For the current segment list, use the data segment DSeg */
|
/* For the current segment context, use the data segment DSeg */
|
||||||
|
|
||||||
struct DataSeg* GetDataSeg (void);
|
struct DataSeg* GetDataSeg (void);
|
||||||
/* Return the current data segment */
|
/* Return the current data segment */
|
||||||
@@ -165,7 +165,7 @@ int HaveGlobalCode (void);
|
|||||||
void RemoveGlobalCode (void);
|
void RemoveGlobalCode (void);
|
||||||
/* Remove all code from the global code segment. Used for error recovery. */
|
/* Remove all code from the global code segment. Used for error recovery. */
|
||||||
|
|
||||||
void OutputSegments (const Segments* S);
|
void OutputSegments (const SegContext* S);
|
||||||
/* Output the given segments to the output file */
|
/* Output the given segments to the output file */
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -56,7 +56,7 @@
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
struct Segments;
|
struct SegContext;
|
||||||
struct LiteralPool;
|
struct LiteralPool;
|
||||||
struct CodeEntry;
|
struct CodeEntry;
|
||||||
|
|
||||||
@@ -156,7 +156,7 @@ struct SymEntry {
|
|||||||
|
|
||||||
/* Data for functions */
|
/* Data for functions */
|
||||||
struct {
|
struct {
|
||||||
struct Segments* Seg; /* Segments for this function */
|
struct SegContext* Seg; /* SegContext for this function */
|
||||||
struct LiteralPool* LitPool; /* Literal pool for this function */
|
struct LiteralPool* LitPool; /* Literal pool for this function */
|
||||||
} F;
|
} F;
|
||||||
|
|
||||||
|
|||||||
@@ -1008,7 +1008,6 @@ SymEntry* AddBitField (const char* Name, const Type* T, unsigned Offs,
|
|||||||
Entry = NewSymEntry (Name, SC_BITFIELD);
|
Entry = NewSymEntry (Name, SC_BITFIELD);
|
||||||
|
|
||||||
/* Set the symbol attributes. Bit-fields are always integral types. */
|
/* Set the symbol attributes. Bit-fields are always integral types. */
|
||||||
Entry->Type = NewBitFieldOf (T, BitOffs, BitWidth);
|
|
||||||
Entry->V.Offs = Offs;
|
Entry->V.Offs = Offs;
|
||||||
|
|
||||||
if (!SignednessSpecified) {
|
if (!SignednessSpecified) {
|
||||||
@@ -1019,12 +1018,10 @@ SymEntry* AddBitField (const char* Name, const Type* T, unsigned Offs,
|
|||||||
** is controlled by `--signed-chars`. In bit-fields, however, we perform the same
|
** is controlled by `--signed-chars`. In bit-fields, however, we perform the same
|
||||||
** `char -> unsigned char` adjustment that is performed with other integral types.
|
** `char -> unsigned char` adjustment that is performed with other integral types.
|
||||||
*/
|
*/
|
||||||
CHECK ((Entry->Type->C & T_MASK_SIGN) == T_SIGN_SIGNED ||
|
CHECK (IsSignSigned (T) || IsRankChar (T));
|
||||||
IsRankChar (Entry->Type));
|
Entry->Type = NewBitFieldOf (GetUnsignedType (T), BitOffs, BitWidth);
|
||||||
Entry->Type[0].C &= ~T_MASK_SIGN;
|
} else {
|
||||||
Entry->Type[0].C |= T_SIGN_UNSIGNED;
|
Entry->Type = NewBitFieldOf (T, BitOffs, BitWidth);
|
||||||
Entry->Type[1].C &= ~T_MASK_SIGN;
|
|
||||||
Entry->Type[1].C |= T_SIGN_UNSIGNED;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Add the entry to the symbol table */
|
/* Add the entry to the symbol table */
|
||||||
|
|||||||
@@ -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)
|
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;
|
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 */
|
/* Compare two types. Determine, where they differ */
|
||||||
while (lhs->C != T_END) {
|
while (lhs->C != T_END && rhs->C != T_END) {
|
||||||
|
|
||||||
/* Check if the end of the type string is reached */
|
|
||||||
if (rhs->C == T_END) {
|
|
||||||
/* End of comparison reached */
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Compare qualifiers */
|
/* Compare qualifiers */
|
||||||
if (CmpQuals (lhs, rhs, Result)->C == TC_INCOMPATIBLE) {
|
if (CmpQuals (lhs, rhs, Result)->C == TC_INCOMPATIBLE) {
|
||||||
|
/* No need to compare further */
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -266,6 +260,22 @@ static void DoCompare (const Type* lhs, const Type* rhs, typecmp_t* Result)
|
|||||||
LeftRank = (GetUnqualTypeCode (lhs) & T_MASK_RANK);
|
LeftRank = (GetUnqualTypeCode (lhs) & T_MASK_RANK);
|
||||||
RightRank = (GetUnqualTypeCode (rhs) & 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
|
/* If one side is a pointer and the other side is an array, both are
|
||||||
** compatible.
|
** 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 the ranks are different, the types are incompatible */
|
||||||
if (LeftRank != RightRank) {
|
if (LeftRank != RightRank) {
|
||||||
SetResult (Result, TC_INCOMPATIBLE);
|
goto Incompatible;
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Enums must be handled specially */
|
/* Enums must be handled specially */
|
||||||
if ((IsTypeEnum (lhs) || IsTypeEnum (rhs))) {
|
if ((IsTypeEnum (lhs) || IsTypeEnum (rhs))) {
|
||||||
|
|
||||||
/* Compare the tag types */
|
/* Compare the tag types */
|
||||||
Sym1 = IsTypeEnum (lhs) ? GetESUTagSym (lhs) : 0;
|
Sym1 = GetESUTagSym (lhs);
|
||||||
Sym2 = IsTypeEnum (rhs) ? GetESUTagSym (rhs) : 0;
|
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 != Sym2) {
|
||||||
if (Sym1 == 0 || Sym2 == 0) {
|
if (Sym1 == 0 || Sym2 == 0) {
|
||||||
|
|
||||||
/* Only one is an enum. So they can't be identical */
|
/* Only one is an enum. So they can't be identical */
|
||||||
SetResult (Result, TC_STRICT_COMPATIBLE);
|
SetResult (Result, TC_STRICT_COMPATIBLE);
|
||||||
|
} else if (Sym1->Owner != Sym2->Owner ||
|
||||||
} else {
|
strcmp (Sym1->Name, Sym2->Name) != 0) {
|
||||||
/* For the two to be identical, they must be in the same
|
/* If any one of the two is incomplete, we can't guess
|
||||||
** scope and have the same name.
|
** their underlying types and have to assume that they
|
||||||
|
** be incompatible.
|
||||||
*/
|
*/
|
||||||
if (Sym1->Owner != Sym2->Owner ||
|
if (SizeOf (lhs) == 0 || SizeOf (rhs) == 0) {
|
||||||
strcmp (Sym1->Name, Sym2->Name) != 0) {
|
goto Incompatible;
|
||||||
|
|
||||||
/* 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;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
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 */
|
/* Check the remaining flags */
|
||||||
if ((F1->Flags & ~FD_IGNORE) != (F2->Flags & ~FD_IGNORE)) {
|
if ((F1->Flags & ~FD_IGNORE) != (F2->Flags & ~FD_IGNORE)) {
|
||||||
/* Flags differ */
|
/* Flags differ */
|
||||||
SetResult (Result, TC_INCOMPATIBLE);
|
goto Incompatible;
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Compare the parameter lists */
|
/* Compare the parameter lists */
|
||||||
if (EqualFuncParams (F1, F2) == 0) {
|
if (EqualFuncParams (F1, F2) == 0) {
|
||||||
/* Parameter list is not identical */
|
/* Parameter list is not identical */
|
||||||
SetResult (Result, TC_INCOMPATIBLE);
|
goto Incompatible;
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -406,8 +393,7 @@ static void DoCompare (const Type* lhs, const Type* rhs, typecmp_t* Result)
|
|||||||
if (LeftCount != UNSPECIFIED &&
|
if (LeftCount != UNSPECIFIED &&
|
||||||
RightCount != UNSPECIFIED) {
|
RightCount != UNSPECIFIED) {
|
||||||
/* Member count given but different */
|
/* Member count given but different */
|
||||||
SetResult (Result, TC_INCOMPATIBLE);
|
goto Incompatible;
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* We take into account which side is more specified */
|
/* 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
|
/* This shouldn't happen in the current code base, but
|
||||||
** we still handle this case to be future-proof.
|
** we still handle this case to be future-proof.
|
||||||
*/
|
*/
|
||||||
SetResult (Result, TC_INCOMPATIBLE);
|
goto Incompatible;
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -453,9 +438,11 @@ static void DoCompare (const Type* lhs, const Type* rhs, typecmp_t* Result)
|
|||||||
/* Check if lhs and rhs both reached ends */
|
/* Check if lhs and rhs both reached ends */
|
||||||
if (lhs->C == T_END && rhs->C == T_END) {
|
if (lhs->C == T_END && rhs->C == T_END) {
|
||||||
SetResult (Result, TC_IDENTICAL);
|
SetResult (Result, TC_IDENTICAL);
|
||||||
} else {
|
return;
|
||||||
SetResult (Result, TC_INCOMPATIBLE);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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)
|
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 NewTypeName = STATIC_STRBUF_INITIALIZER;
|
||||||
StrBuf OldTypeName = STATIC_STRBUF_INITIALIZER;
|
StrBuf OldTypeName = STATIC_STRBUF_INITIALIZER;
|
||||||
|
|||||||
@@ -97,7 +97,10 @@ typecmp_t TypeCmp (const Type* lhs, const Type* rhs);
|
|||||||
/* Compare two types and return the result */
|
/* Compare two types and return the result */
|
||||||
|
|
||||||
void TypeCompatibilityDiagnostic (const Type* NewType, const Type* OldType, int IsError, const char* Msg);
|
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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user