mirror of
https://github.com/cc65/cc65.git
synced 2024-06-28 03:29:39 +00:00
Complete redesign of line info generation. Uses spans instead of a fragment
list as before. git-svn-id: svn://svn.cc65.org/cc65/trunk@5162 b7a2c559-68d2-44c3-8de9-860c34a00d81
This commit is contained in:
parent
e67c802193
commit
b8549f0af8
|
@ -487,7 +487,7 @@ void CheckOpenIfs (void)
|
||||||
}
|
}
|
||||||
|
|
||||||
LI = CollConstAt (&D->LineInfos, 0);
|
LI = CollConstAt (&D->LineInfos, 0);
|
||||||
if (LI->Pos.Name != CurTok.Pos.Name) {
|
if (GetSourcePos (LI)->Name != CurTok.Pos.Name) {
|
||||||
/* The .if is from another file, bail out */
|
/* The .if is from another file, bail out */
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
@ -49,7 +49,18 @@
|
||||||
|
|
||||||
|
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
/* Code */
|
/* Data */
|
||||||
|
/*****************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* The current line info */
|
||||||
|
static LineInfo* CurLineInfo = 0;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*****************************************************************************/
|
||||||
|
/* Code */
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
@ -99,11 +110,16 @@ void DbgInfoLine (void)
|
||||||
long Line;
|
long Line;
|
||||||
FilePos Pos = STATIC_FILEPOS_INITIALIZER;
|
FilePos Pos = STATIC_FILEPOS_INITIALIZER;
|
||||||
|
|
||||||
|
/* Any new line info terminates the last one */
|
||||||
|
if (CurLineInfo) {
|
||||||
|
EndLine (CurLineInfo);
|
||||||
|
CurLineInfo = 0;
|
||||||
|
}
|
||||||
|
|
||||||
/* If a parameters follow, this is actual line info. If no parameters
|
/* If a parameters follow, this is actual line info. If no parameters
|
||||||
* follow, the last line info is terminated.
|
* follow, the last line info is terminated.
|
||||||
*/
|
*/
|
||||||
if (CurTok.Tok == TOK_SEP) {
|
if (CurTok.Tok == TOK_SEP) {
|
||||||
ClearLineInfo (LI_SLOT_EXT);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -133,8 +149,8 @@ void DbgInfoLine (void)
|
||||||
}
|
}
|
||||||
Pos.Line = Line;
|
Pos.Line = Line;
|
||||||
|
|
||||||
/* Remember the line info */
|
/* Generate a new external line info */
|
||||||
GenLineInfo (LI_SLOT_EXT, &Pos);
|
CurLineInfo = StartLine (&Pos, LI_TYPE_EXT, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -61,7 +61,7 @@
|
||||||
static unsigned HT_GenHash (const void* Key);
|
static unsigned HT_GenHash (const void* Key);
|
||||||
/* Generate the hash over a key. */
|
/* Generate the hash over a key. */
|
||||||
|
|
||||||
static const void* HT_GetKey (void* Entry);
|
static const void* HT_GetKey (const void* Entry);
|
||||||
/* Given a pointer to the user entry data, return a pointer to the key. */
|
/* Given a pointer to the user entry data, return a pointer to the key. */
|
||||||
|
|
||||||
static int HT_Compare (const void* Key1, const void* Key2);
|
static int HT_Compare (const void* Key1, const void* Key2);
|
||||||
|
@ -122,7 +122,7 @@ static unsigned HT_GenHash (const void* Key)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
static const void* HT_GetKey (void* Entry)
|
static const void* HT_GetKey (const void* Entry)
|
||||||
/* Given a pointer to the user entry data, return a pointer to the index */
|
/* Given a pointer to the user entry data, return a pointer to the index */
|
||||||
{
|
{
|
||||||
return &((FileEntry*) Entry)->Name;
|
return &((FileEntry*) Entry)->Name;
|
||||||
|
@ -134,7 +134,7 @@ static int HT_Compare (const void* Key1, const void* Key2)
|
||||||
/* Compare two keys. The function must return a value less than zero if
|
/* Compare two keys. The function must return a value less than zero if
|
||||||
* Key1 is smaller than Key2, zero if both are equal, and a value greater
|
* Key1 is smaller than Key2, zero if both are equal, and a value greater
|
||||||
* than zero if Key1 is greater then Key2.
|
* than zero if Key1 is greater then Key2.
|
||||||
*/
|
*/
|
||||||
{
|
{
|
||||||
return (int)*(const unsigned*)Key1 - (int)*(const unsigned*)Key2;
|
return (int)*(const unsigned*)Key1 - (int)*(const unsigned*)Key2;
|
||||||
}
|
}
|
||||||
|
|
|
@ -34,16 +34,38 @@
|
||||||
|
|
||||||
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <limits.h>
|
|
||||||
|
|
||||||
/* common */
|
/* common */
|
||||||
#include "coll.h"
|
#include "coll.h"
|
||||||
|
#include "hashfunc.h"
|
||||||
#include "xmalloc.h"
|
#include "xmalloc.h"
|
||||||
|
|
||||||
/* ca65 */
|
/* ca65 */
|
||||||
#include "global.h"
|
#include "global.h"
|
||||||
#include "lineinfo.h"
|
#include "lineinfo.h"
|
||||||
#include "objfile.h"
|
#include "objfile.h"
|
||||||
|
#include "scanner.h"
|
||||||
|
#include "span.h"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*****************************************************************************/
|
||||||
|
/* Forwards */
|
||||||
|
/*****************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
static unsigned HT_GenHash (const void* Key);
|
||||||
|
/* Generate the hash over a key. */
|
||||||
|
|
||||||
|
static const void* HT_GetKey (const void* Entry);
|
||||||
|
/* Given a pointer to the user entry data, return a pointer to the key */
|
||||||
|
|
||||||
|
static int HT_Compare (const void* Key1, const void* Key2);
|
||||||
|
/* Compare two keys. The function must return a value less than zero if
|
||||||
|
* Key1 is smaller than Key2, zero if both are equal, and a value greater
|
||||||
|
* than zero if Key1 is greater then Key2.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -53,26 +75,99 @@
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* An invalid line info index */
|
/* Structure that holds the key for a line info */
|
||||||
#define INV_LINEINFO_INDEX UINT_MAX
|
typedef struct LineInfoKey LineInfoKey;
|
||||||
|
struct LineInfoKey {
|
||||||
/* Collection containing all line infos */
|
FilePos Pos; /* File position */
|
||||||
static Collection LineInfoColl = STATIC_COLLECTION_INITIALIZER;
|
unsigned short Type; /* Type of line info */
|
||||||
|
unsigned short Count; /* Recursion counter */
|
||||||
/* Number of valid (=used) line infos in LineInfoColl */
|
|
||||||
static unsigned UsedLineInfoCount;
|
|
||||||
|
|
||||||
/* Entry in CurLineInfo */
|
|
||||||
typedef struct LineInfoSlot LineInfoSlot;
|
|
||||||
struct LineInfoSlot {
|
|
||||||
unsigned Type;
|
|
||||||
LineInfo* Info;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Dynamically allocated array of LineInfoSlots */
|
/* Structure that holds line info */
|
||||||
static LineInfoSlot* CurLineInfo;
|
struct LineInfo {
|
||||||
static unsigned AllocatedSlots;
|
HashNode Node; /* Hash table node */
|
||||||
static unsigned UsedSlots;
|
unsigned Id; /* Index */
|
||||||
|
LineInfoKey Key; /* Key for this line info */
|
||||||
|
unsigned char Hashed; /* True if in hash list */
|
||||||
|
unsigned char Referenced; /* Force reference even if no spans */
|
||||||
|
Collection Spans; /* Segment spans for this line info */
|
||||||
|
Collection OpenSpans; /* List of currently open spans */
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* Collection containing all line infos */
|
||||||
|
static Collection LineInfoList = STATIC_COLLECTION_INITIALIZER;
|
||||||
|
|
||||||
|
/* Collection with currently active line infos */
|
||||||
|
static Collection CurLineInfo = STATIC_COLLECTION_INITIALIZER;
|
||||||
|
|
||||||
|
/* Hash table functions */
|
||||||
|
static const HashFunctions HashFunc = {
|
||||||
|
HT_GenHash,
|
||||||
|
HT_GetKey,
|
||||||
|
HT_Compare
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Line info hash table */
|
||||||
|
static HashTable LineInfoTab = STATIC_HASHTABLE_INITIALIZER (1051, &HashFunc);
|
||||||
|
|
||||||
|
/* The current assembler input line */
|
||||||
|
static LineInfo* AsmLineInfo = 0;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*****************************************************************************/
|
||||||
|
/* Hash table functions */
|
||||||
|
/*****************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
static unsigned HT_GenHash (const void* Key)
|
||||||
|
/* Generate the hash over a key. */
|
||||||
|
{
|
||||||
|
/* Key is a LineInfoKey pointer */
|
||||||
|
const LineInfoKey* K = Key;
|
||||||
|
|
||||||
|
/* Hash over a combination of type, file and line */
|
||||||
|
return HashInt ((K->Type << 18) ^ (K->Pos.Name << 14) ^ K->Pos.Line);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
static const void* HT_GetKey (const void* Entry)
|
||||||
|
/* Given a pointer to the user entry data, return a pointer to the key */
|
||||||
|
{
|
||||||
|
return &((const LineInfo*)Entry)->Key;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
static int HT_Compare (const void* Key1, const void* Key2)
|
||||||
|
/* Compare two keys. The function must return a value less than zero if
|
||||||
|
* Key1 is smaller than Key2, zero if both are equal, and a value greater
|
||||||
|
* than zero if Key1 is greater then Key2.
|
||||||
|
*/
|
||||||
|
{
|
||||||
|
/* Convert both parameters to FileInfoKey pointers */
|
||||||
|
const LineInfoKey* K1 = Key1;
|
||||||
|
const LineInfoKey* K2 = Key2;
|
||||||
|
|
||||||
|
/* Compare line number, then file and type, then count */
|
||||||
|
int Res = (int)K2->Pos.Line - (int)K1->Pos.Line;
|
||||||
|
if (Res == 0) {
|
||||||
|
Res = (int)K2->Pos.Name - (int)K1->Pos.Name;
|
||||||
|
if (Res == 0) {
|
||||||
|
Res = (int)K2->Type - (int)K1->Type;
|
||||||
|
if (Res == 0) {
|
||||||
|
Res = (int)K2->Count - (int)K1->Count;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Done */
|
||||||
|
return Res;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -82,20 +177,20 @@ static unsigned UsedSlots;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
static LineInfo* NewLineInfo (unsigned Type, const FilePos* Pos)
|
static LineInfo* NewLineInfo (const LineInfoKey* Key)
|
||||||
/* Create and return a new line info. Usage will be zero. */
|
/* Create and return a new line info. Usage will be zero. */
|
||||||
{
|
{
|
||||||
/* Allocate memory */
|
/* Allocate memory */
|
||||||
LineInfo* LI = xmalloc (sizeof (LineInfo));
|
LineInfo* LI = xmalloc (sizeof (LineInfo));
|
||||||
|
|
||||||
/* Initialize the fields */
|
/* Initialize the fields */
|
||||||
LI->Usage = 0;
|
InitHashNode (&LI->Node);
|
||||||
LI->Type = Type;
|
LI->Id = ~0U;
|
||||||
LI->Index = INV_LINEINFO_INDEX;
|
LI->Key = *Key;
|
||||||
LI->Pos = *Pos;
|
LI->Hashed = 0;
|
||||||
|
LI->Referenced= 0;
|
||||||
/* Add the line info to the list of all line infos */
|
InitCollection (&LI->Spans);
|
||||||
CollAppend (&LineInfoColl, LI);
|
InitCollection (&LI->OpenSpans);
|
||||||
|
|
||||||
/* Return the new struct */
|
/* Return the new struct */
|
||||||
return LI;
|
return LI;
|
||||||
|
@ -103,6 +198,40 @@ static LineInfo* NewLineInfo (unsigned Type, const FilePos* Pos)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
static void FreeLineInfo (LineInfo* LI)
|
||||||
|
/* Free a LineInfo structure */
|
||||||
|
{
|
||||||
|
/* Free the Spans collection. It is supposed to be empty */
|
||||||
|
CHECK (CollCount (&LI->Spans) == 0);
|
||||||
|
DoneCollection (&LI->Spans);
|
||||||
|
DoneCollection (&LI->OpenSpans);
|
||||||
|
|
||||||
|
/* Free the structure itself */
|
||||||
|
xfree (LI);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
static void RememberLineInfo (LineInfo* LI)
|
||||||
|
/* Remember a LineInfo by adding it to the hash table and the global list.
|
||||||
|
* This will also assign the id which is actually the list position.
|
||||||
|
*/
|
||||||
|
{
|
||||||
|
/* Assign the id */
|
||||||
|
LI->Id = CollCount (&LineInfoList);
|
||||||
|
|
||||||
|
/* Remember it in the global list */
|
||||||
|
CollAppend (&LineInfoList, LI);
|
||||||
|
|
||||||
|
/* Add it to the hash table, so we will find it if necessary */
|
||||||
|
HT_InsertEntry (&LineInfoTab, LI);
|
||||||
|
|
||||||
|
/* Remember that we have it */
|
||||||
|
LI->Hashed = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
/* Code */
|
/* Code */
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
|
@ -115,94 +244,128 @@ void InitLineInfo (void)
|
||||||
static const FilePos DefaultPos = STATIC_FILEPOS_INITIALIZER;
|
static const FilePos DefaultPos = STATIC_FILEPOS_INITIALIZER;
|
||||||
|
|
||||||
/* Increase the initial count of the line info collection */
|
/* Increase the initial count of the line info collection */
|
||||||
CollGrow (&LineInfoColl, 200);
|
CollGrow (&LineInfoList, 200);
|
||||||
|
|
||||||
/* Allocate 8 slots */
|
/* Create a LineInfo for the default source. This is necessary to allow
|
||||||
AllocatedSlots = 8;
|
* error message to be generated without any input file open.
|
||||||
CurLineInfo = xmalloc (AllocatedSlots * sizeof (LineInfoSlot));
|
|
||||||
|
|
||||||
/* Initalize the predefined slots. Be sure to create a new LineInfo for
|
|
||||||
* the default source. This is necessary to allow error message to be
|
|
||||||
* generated without any input file open.
|
|
||||||
*/
|
*/
|
||||||
UsedSlots = 2;
|
AsmLineInfo = StartLine (&DefaultPos, LI_TYPE_ASM, 0);
|
||||||
CurLineInfo[LI_SLOT_ASM].Type = LI_TYPE_ASM; /* Count = 0 */
|
|
||||||
CurLineInfo[LI_SLOT_ASM].Info = NewLineInfo (LI_TYPE_ASM, &DefaultPos);
|
|
||||||
CurLineInfo[LI_SLOT_EXT].Type = LI_TYPE_EXT; /* Count = 0 */
|
|
||||||
CurLineInfo[LI_SLOT_EXT].Info = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
int AllocLineInfoSlot (unsigned Type, unsigned Count)
|
void DoneLineInfo (void)
|
||||||
/* Allocate a line info slot of the given type and return the slot index */
|
/* Close down line infos */
|
||||||
{
|
{
|
||||||
/* Grow the array if necessary */
|
/* Close all current line infos */
|
||||||
if (UsedSlots >= AllocatedSlots) {
|
unsigned Count = CollCount (&CurLineInfo);
|
||||||
LineInfoSlot* NewLineInfo;
|
while (Count) {
|
||||||
AllocatedSlots *= 2;
|
EndLine (CollAt (&CurLineInfo, --Count));
|
||||||
NewLineInfo = xmalloc (AllocatedSlots * sizeof (LineInfoSlot));
|
}
|
||||||
memcpy (NewLineInfo, CurLineInfo, UsedSlots * sizeof (LineInfoSlot));
|
}
|
||||||
xfree (CurLineInfo);
|
|
||||||
CurLineInfo = NewLineInfo;
|
|
||||||
|
|
||||||
|
void EndLine (LineInfo* LI)
|
||||||
|
/* End a line that is tracked by the given LineInfo structure */
|
||||||
|
{
|
||||||
|
unsigned I;
|
||||||
|
|
||||||
|
/* Close the spans for the line */
|
||||||
|
CloseSpans (&LI->OpenSpans);
|
||||||
|
|
||||||
|
/* Move the spans to the list of all spans for this line, then clear the
|
||||||
|
* list of open spans.
|
||||||
|
*/
|
||||||
|
for (I = 0; I < CollCount (&LI->OpenSpans); ++I) {
|
||||||
|
CollAppend (&LI->Spans, CollAtUnchecked (&LI->OpenSpans, I));
|
||||||
|
}
|
||||||
|
CollDeleteAll (&LI->OpenSpans);
|
||||||
|
|
||||||
|
/* Line info is no longer active - remove it from the list of current
|
||||||
|
* line infos.
|
||||||
|
*/
|
||||||
|
CollDeleteItem (&CurLineInfo, LI);
|
||||||
|
|
||||||
|
/* If this line info is already hashed, we're done. Otherwise, if it is
|
||||||
|
* marked as referenced or has non empty spans, remember it. It it is not
|
||||||
|
* referenced or doesn't have open spans, delete it.
|
||||||
|
*/
|
||||||
|
if (!LI->Hashed) {
|
||||||
|
if (LI->Referenced || CollCount (&LI->Spans) > 0) {
|
||||||
|
RememberLineInfo (LI);
|
||||||
|
} else {
|
||||||
|
FreeLineInfo (LI);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
LineInfo* StartLine (const FilePos* Pos, unsigned Type, unsigned Count)
|
||||||
|
/* Start line info for a new line */
|
||||||
|
{
|
||||||
|
LineInfoKey Key;
|
||||||
|
LineInfo* LI;
|
||||||
|
|
||||||
|
/* Prepare the key struct */
|
||||||
|
Key.Pos = *Pos;
|
||||||
|
Key.Type = Type;
|
||||||
|
Key.Count = Count;
|
||||||
|
|
||||||
|
/* Try to find a line info with this position and type in the hash table.
|
||||||
|
* If so, reuse it. Otherwise create a new one.
|
||||||
|
*/
|
||||||
|
LI = HT_FindEntry (&LineInfoTab, &Key);
|
||||||
|
if (LI == 0) {
|
||||||
|
/* Allocate a new LineInfo */
|
||||||
|
LI = NewLineInfo (&Key);
|
||||||
|
} else {
|
||||||
|
Key.Count = 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Array is now big enough, add the new data */
|
/* Open the spans for this line info */
|
||||||
CurLineInfo[UsedSlots].Type = LI_MAKE_TYPE(Type, Count);
|
OpenSpans (&LI->OpenSpans);
|
||||||
CurLineInfo[UsedSlots].Info = 0;
|
|
||||||
|
|
||||||
/* Increment the count and return the index of the new slot */
|
/* Add the line info to the list of current line infos */
|
||||||
return (int) UsedSlots++;
|
CollAppend (&CurLineInfo, LI);
|
||||||
|
|
||||||
|
/* Return the new info */
|
||||||
|
return LI;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void FreeLineInfoSlot (int Slot)
|
void NewAsmLine (void)
|
||||||
/* Free the line info in the given slot. Note: Alloc/Free must be used in
|
/* Start a new assembler input line. Use this function when generating new
|
||||||
* FIFO order.
|
* line of LI_TYPE_ASM. It will check if line and/or file have actually
|
||||||
|
* changed, end the old and start the new line as necessary.
|
||||||
*/
|
*/
|
||||||
{
|
{
|
||||||
/* Check the parameter */
|
/* Check if we can reuse the old line */
|
||||||
PRECONDITION (Slot == (int) UsedSlots - 1);
|
if (AsmLineInfo) {
|
||||||
|
if (AsmLineInfo->Key.Pos.Line == CurTok.Pos.Line &&
|
||||||
|
AsmLineInfo->Key.Pos.Name == CurTok.Pos.Name) {
|
||||||
|
/* We do already have line info for this line */
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
/* Free the last entry */
|
/* Line has changed -> end the old line */
|
||||||
CurLineInfo[Slot].Info = 0;
|
EndLine (AsmLineInfo);
|
||||||
--UsedSlots;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void GenLineInfo (int Slot, const FilePos* Pos)
|
|
||||||
/* Generate a new line info in the given slot */
|
|
||||||
{
|
|
||||||
/* Get a pointer to the slot */
|
|
||||||
LineInfoSlot* S = CurLineInfo + Slot;
|
|
||||||
|
|
||||||
/* Generate new data only if it is different from the existing. */
|
|
||||||
if (S->Info && CompareFilePos (&S->Info->Pos, Pos) == 0) {
|
|
||||||
/* Already there */
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Allocate new data */
|
/* Start a new line using the current line info */
|
||||||
S->Info = NewLineInfo (S->Type, Pos);
|
AsmLineInfo = StartLine (&CurTok.Pos, LI_TYPE_ASM, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void ClearLineInfo (int Slot)
|
void GetFullLineInfo (Collection* LineInfos, int ForceRef)
|
||||||
/* Clear the line info in the given slot */
|
/* Return full line infos, that is line infos for currently active Slots. The
|
||||||
{
|
* function will clear LineInfos before usage. If ForceRef is not zero, a
|
||||||
/* Zero the pointer */
|
* forced reference will be added to all line infos, with the consequence that
|
||||||
CurLineInfo[Slot].Info = 0;
|
* they won't get deleted, even if there is no code or data generated for these
|
||||||
}
|
* lines.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void GetFullLineInfo (Collection* LineInfos, unsigned IncUsage)
|
|
||||||
/* Return full line infos, that is line infos for all slots in LineInfos. The
|
|
||||||
* function will clear LineInfos before usage and will increment the usage
|
|
||||||
* counter by IncUsage for all line infos returned.
|
|
||||||
*/
|
*/
|
||||||
{
|
{
|
||||||
unsigned I;
|
unsigned I;
|
||||||
|
@ -210,66 +373,45 @@ void GetFullLineInfo (Collection* LineInfos, unsigned IncUsage)
|
||||||
/* Clear the collection */
|
/* Clear the collection */
|
||||||
CollDeleteAll (LineInfos);
|
CollDeleteAll (LineInfos);
|
||||||
|
|
||||||
|
/* Grow the collection as necessary */
|
||||||
|
CollGrow (LineInfos, CollCount (&CurLineInfo));
|
||||||
|
|
||||||
/* Copy all valid line infos to the collection */
|
/* Copy all valid line infos to the collection */
|
||||||
for (I = 0; I < UsedSlots; ++I) {
|
for (I = 0; I < CollCount (&CurLineInfo); ++I) {
|
||||||
|
|
||||||
/* Get the line info from the slot */
|
/* Get the line info from the slot */
|
||||||
LineInfo* LI = CurLineInfo[I].Info;
|
LineInfo* LI = CollAt (&CurLineInfo, I);
|
||||||
|
|
||||||
/* Ignore empty slots */
|
/* Mark it as referenced */
|
||||||
if (LI) {
|
if (ForceRef) {
|
||||||
LI->Usage += IncUsage;
|
LI->Referenced = 1;
|
||||||
CollAppend (LineInfos, LI);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Return it to the caller */
|
||||||
|
CollAppend (LineInfos, LI);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
LineInfo* ReleaseLineInfo (LineInfo* LI)
|
const FilePos* GetSourcePos (const LineInfo* LI)
|
||||||
/* Decrease the reference count of the given line info and return it. The
|
/* Return the source file position from the given line info */
|
||||||
* function will gracefully accept NULL pointers and do nothing in this case.
|
|
||||||
*/
|
|
||||||
{
|
{
|
||||||
if (LI) {
|
return &LI->Key.Pos;
|
||||||
/* Cannot decrease below zero */
|
|
||||||
CHECK (LI->Usage != 0);
|
|
||||||
--LI->Usage;
|
|
||||||
}
|
|
||||||
return LI;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
static int CmpLineInfo (void* Data attribute ((unused)),
|
unsigned GetLineInfoType (const LineInfo* LI)
|
||||||
const void* LI1_, const void* LI2_)
|
/* Return the type of a line info */
|
||||||
/* Compare function for the sort */
|
|
||||||
{
|
{
|
||||||
/* Cast the pointers */
|
return LI_GET_TYPE (LI->Key.Type);
|
||||||
const LineInfo* LI1 = LI1_;
|
|
||||||
const LineInfo* LI2 = LI2_;
|
|
||||||
|
|
||||||
/* Unreferenced line infos are always larger, otherwise sort by file,
|
|
||||||
* then by line, then by column.
|
|
||||||
*/
|
|
||||||
if ((LI1->Usage == 0) == (LI2->Usage == 0)) {
|
|
||||||
/* Both are either referenced or unreferenced */
|
|
||||||
return CompareFilePos (&LI1->Pos, &LI2->Pos);
|
|
||||||
} else {
|
|
||||||
if (LI1->Usage > 0) {
|
|
||||||
return -1;
|
|
||||||
} else {
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void WriteLineInfo (const Collection* LineInfos)
|
void WriteLineInfo (const Collection* LineInfos)
|
||||||
/* Write a list of line infos to the object file. MakeLineInfoIndex has to
|
/* Write a list of line infos to the object file. */
|
||||||
* be called before!
|
|
||||||
*/
|
|
||||||
{
|
{
|
||||||
unsigned I;
|
unsigned I;
|
||||||
|
|
||||||
|
@ -282,40 +424,10 @@ void WriteLineInfo (const Collection* LineInfos)
|
||||||
/* Get a pointer to the line info */
|
/* Get a pointer to the line info */
|
||||||
const LineInfo* LI = CollConstAt (LineInfos, I);
|
const LineInfo* LI = CollConstAt (LineInfos, I);
|
||||||
|
|
||||||
/* Check the index */
|
CHECK (LI->Id != ~0U);
|
||||||
CHECK (LI->Index != INV_LINEINFO_INDEX);
|
|
||||||
|
|
||||||
/* Write the index to the file */
|
/* Write the index to the file */
|
||||||
ObjWriteVar (LI->Index);
|
ObjWriteVar (LI->Id);
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void MakeLineInfoIndex (void)
|
|
||||||
/* Index the line infos */
|
|
||||||
{
|
|
||||||
unsigned I;
|
|
||||||
|
|
||||||
/* Sort the line info list */
|
|
||||||
CollSort (&LineInfoColl, CmpLineInfo, 0);
|
|
||||||
|
|
||||||
/* Walk over the list, index the line infos and count the used ones */
|
|
||||||
UsedLineInfoCount = 0;
|
|
||||||
for (I = 0; I < CollCount (&LineInfoColl); ++I) {
|
|
||||||
/* Get a pointer to this line info */
|
|
||||||
LineInfo* LI = CollAtUnchecked (&LineInfoColl, I);
|
|
||||||
|
|
||||||
/* If it is invalid, terminate the loop. All unused line infos were
|
|
||||||
* placed at the end of the collection by the sort.
|
|
||||||
*/
|
|
||||||
if (LI->Usage == 0) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Index and count this one */
|
|
||||||
LI->Index = I;
|
|
||||||
++UsedLineInfoCount;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -330,18 +442,22 @@ void WriteLineInfos (void)
|
||||||
ObjStartLineInfos ();
|
ObjStartLineInfos ();
|
||||||
|
|
||||||
/* Write the line info count to the list */
|
/* Write the line info count to the list */
|
||||||
ObjWriteVar (UsedLineInfoCount);
|
ObjWriteVar (CollCount (&LineInfoList));
|
||||||
|
|
||||||
/* Walk over the list and write all line infos */
|
/* Walk over the list and write all line infos */
|
||||||
for (I = 0; I < UsedLineInfoCount; ++I) {
|
for (I = 0; I < CollCount (&LineInfoList); ++I) {
|
||||||
/* Get a pointer to this line info */
|
|
||||||
LineInfo* LI = CollAt (&LineInfoColl, I);
|
|
||||||
|
|
||||||
/* Write the type and count of the line info */
|
/* Get a pointer to this line info */
|
||||||
ObjWriteVar (LI->Type);
|
LineInfo* LI = CollAt (&LineInfoList, I);
|
||||||
|
|
||||||
/* Write the source file position */
|
/* Write the source file position */
|
||||||
ObjWritePos (&LI->Pos);
|
ObjWritePos (&LI->Key.Pos);
|
||||||
|
|
||||||
|
/* Write the type and count of the line info */
|
||||||
|
ObjWriteVar (LI_MAKE_TYPE (LI->Key.Type, LI->Key.Count));
|
||||||
|
|
||||||
|
/* Write the spans for this line */
|
||||||
|
WriteSpans (&LI->Spans);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* End of line infos */
|
/* End of line infos */
|
||||||
|
|
|
@ -41,6 +41,7 @@
|
||||||
/* common */
|
/* common */
|
||||||
#include "coll.h"
|
#include "coll.h"
|
||||||
#include "filepos.h"
|
#include "filepos.h"
|
||||||
|
#include "hashtab.h"
|
||||||
#include "lidefs.h"
|
#include "lidefs.h"
|
||||||
|
|
||||||
|
|
||||||
|
@ -51,26 +52,8 @@
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* Predefined line info slots. These are allocated when initializing the
|
/* Opaque structure used to handle line information */
|
||||||
* module. Beware: Some code relies on the fact that slot zero is the basic
|
|
||||||
* standard line info. It is assumed to be always there.
|
|
||||||
*/
|
|
||||||
enum {
|
|
||||||
LI_SLOT_INV = -1, /* Use to mark invalid slots */
|
|
||||||
LI_SLOT_ASM = 0, /* Normal assembler source */
|
|
||||||
LI_SLOT_EXT = 1, /* Externally supplied line info */
|
|
||||||
};
|
|
||||||
|
|
||||||
/* The LineInfo structure is shared between several fragments, so we need a
|
|
||||||
* reference counter.
|
|
||||||
*/
|
|
||||||
typedef struct LineInfo LineInfo;
|
typedef struct LineInfo LineInfo;
|
||||||
struct LineInfo {
|
|
||||||
unsigned Usage; /* Usage counter */
|
|
||||||
unsigned Type; /* Type of line info */
|
|
||||||
unsigned Index; /* Index */
|
|
||||||
FilePos Pos; /* File position */
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -83,58 +66,37 @@ struct LineInfo {
|
||||||
void InitLineInfo (void);
|
void InitLineInfo (void);
|
||||||
/* Initialize the line infos */
|
/* Initialize the line infos */
|
||||||
|
|
||||||
int AllocLineInfoSlot (unsigned Type, unsigned Count);
|
void DoneLineInfo (void);
|
||||||
/* Allocate a line info slot of the given type and return the slot index */
|
/* Close down line infos */
|
||||||
|
|
||||||
void FreeLineInfoSlot (int Slot);
|
void EndLine (LineInfo* LI);
|
||||||
/* Free the line info in the given slot. Note: Alloc/Free must be used in
|
/* End a line that is tracked by the given LineInfo structure */
|
||||||
* FIFO order.
|
|
||||||
|
LineInfo* StartLine (const FilePos* Pos, unsigned Type, unsigned Count);
|
||||||
|
/* Start line info for a new line */
|
||||||
|
|
||||||
|
void NewAsmLine (void);
|
||||||
|
/* Start a new assembler input line. Use this function when generating new
|
||||||
|
* line of LI_TYPE_ASM. It will check if line and/or file have actually
|
||||||
|
* changed, end the old and start the new line as necessary.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
void GenLineInfo (int Slot, const FilePos* Pos);
|
void GetFullLineInfo (Collection* LineInfos, int ForceRef);
|
||||||
/* Generate a new line info in the given slot */
|
/* Return full line infos, that is line infos for currently active Slots. The
|
||||||
|
* function will clear LineInfos before usage. If ForceRef is not zero, a
|
||||||
void ClearLineInfo (int Slot);
|
* forced reference will be added to all line infos, with the consequence that
|
||||||
/* Clear the line info in the given slot */
|
* they won't get deleted, even if there is no code or data generated for these
|
||||||
|
* lines.
|
||||||
void GetFullLineInfo (Collection* LineInfos, unsigned IncUsage);
|
|
||||||
/* Return full line infos, that is line infos for all slots in LineInfos. The
|
|
||||||
* function will clear LineInfos before usage and will increment the usage
|
|
||||||
* counter by IncUsage for all line infos returned.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
LineInfo* ReleaseLineInfo (LineInfo* LI);
|
const FilePos* GetSourcePos (const LineInfo* LI);
|
||||||
/* Decrease the reference count of the given line info and return it. The
|
|
||||||
* function will gracefully accept NULL pointers and do nothing in this case.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#if defined(HAVE_INLINE)
|
|
||||||
INLINE const FilePos* GetSourcePos (const LineInfo* LI)
|
|
||||||
/* Return the source file position from the given line info */
|
/* Return the source file position from the given line info */
|
||||||
{
|
|
||||||
return &LI->Pos;
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
# define GetSourcePos(LI) (&(LI)->Pos)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if defined(HAVE_INLINE)
|
unsigned GetLineInfoType (const LineInfo* LI);
|
||||||
INLINE unsigned GetLineInfoType (const LineInfo* LI)
|
|
||||||
/* Return the type of a line info */
|
/* Return the type of a line info */
|
||||||
{
|
|
||||||
return LI_GET_TYPE (LI->Type);
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
# define GetLineInfoType(LI) LI_GET_TYPE ((LI)->Type)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
void WriteLineInfo (const Collection* LineInfos);
|
void WriteLineInfo (const Collection* LineInfos);
|
||||||
/* Write a list of line infos to the object file. MakeLineInfoIndex has to
|
/* Write a list of line infos to the object file. */
|
||||||
* be called before!
|
|
||||||
*/
|
|
||||||
|
|
||||||
void MakeLineInfoIndex (void);
|
|
||||||
/* Index the line infos */
|
|
||||||
|
|
||||||
void WriteLineInfos (void);
|
void WriteLineInfos (void);
|
||||||
/* Write a list of all line infos to the object file. */
|
/* Write a list of all line infos to the object file. */
|
||||||
|
|
|
@ -65,7 +65,7 @@
|
||||||
static unsigned HT_GenHash (const void* Key);
|
static unsigned HT_GenHash (const void* Key);
|
||||||
/* Generate the hash over a key. */
|
/* Generate the hash over a key. */
|
||||||
|
|
||||||
static const void* HT_GetKey (void* Entry);
|
static const void* HT_GetKey (const void* Entry);
|
||||||
/* Given a pointer to the user entry data, return a pointer to the key */
|
/* Given a pointer to the user entry data, return a pointer to the key */
|
||||||
|
|
||||||
static int HT_Compare (const void* Key1, const void* Key2);
|
static int HT_Compare (const void* Key1, const void* Key2);
|
||||||
|
@ -130,7 +130,7 @@ struct MacExp {
|
||||||
unsigned ParamCount; /* Number of actual parameters */
|
unsigned ParamCount; /* Number of actual parameters */
|
||||||
TokNode** Params; /* List of actual parameters */
|
TokNode** Params; /* List of actual parameters */
|
||||||
TokNode* ParamExp; /* Node for expanding parameters */
|
TokNode* ParamExp; /* Node for expanding parameters */
|
||||||
int LISlot; /* Slot for additional line infos */
|
LineInfo* LI; /* Line info for the expansion */
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Maximum number of nested macro expansions */
|
/* Maximum number of nested macro expansions */
|
||||||
|
@ -164,7 +164,7 @@ static unsigned HT_GenHash (const void* Key)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
static const void* HT_GetKey (void* Entry)
|
static const void* HT_GetKey (const void* Entry)
|
||||||
/* Given a pointer to the user entry data, return a pointer to the index */
|
/* Given a pointer to the user entry data, return a pointer to the index */
|
||||||
{
|
{
|
||||||
return &((Macro*) Entry)->Name;
|
return &((Macro*) Entry)->Name;
|
||||||
|
@ -307,7 +307,7 @@ static MacExp* NewMacExp (Macro* M)
|
||||||
E->Params[I] = 0;
|
E->Params[I] = 0;
|
||||||
}
|
}
|
||||||
E->ParamExp = 0;
|
E->ParamExp = 0;
|
||||||
E->LISlot = AllocLineInfoSlot (LI_TYPE_MACRO, MacExpansions);
|
E->LI = 0;
|
||||||
|
|
||||||
/* Mark the macro as expanding */
|
/* Mark the macro as expanding */
|
||||||
++M->Expansions;
|
++M->Expansions;
|
||||||
|
@ -344,8 +344,10 @@ static void FreeMacExp (MacExp* E)
|
||||||
}
|
}
|
||||||
xfree (E->Params);
|
xfree (E->Params);
|
||||||
|
|
||||||
/* Free the additional line info slot */
|
/* Free the additional line info */
|
||||||
FreeLineInfoSlot (E->LISlot);
|
if (E->LI) {
|
||||||
|
EndLine (E->LI);
|
||||||
|
}
|
||||||
|
|
||||||
/* Free the final token if we have one */
|
/* Free the final token if we have one */
|
||||||
if (E->Final) {
|
if (E->Final) {
|
||||||
|
@ -644,8 +646,8 @@ static int MacExpand (void* Data)
|
||||||
ExpandParam:
|
ExpandParam:
|
||||||
if (Mac->ParamExp) {
|
if (Mac->ParamExp) {
|
||||||
|
|
||||||
/* Ok, use token from parameter list, but don't use its line info */
|
/* Ok, use token from parameter list */
|
||||||
TokSet (Mac->ParamExp, LI_SLOT_INV);
|
TokSet (Mac->ParamExp);
|
||||||
|
|
||||||
/* Set pointer to next token */
|
/* Set pointer to next token */
|
||||||
Mac->ParamExp = Mac->ParamExp->Next;
|
Mac->ParamExp = Mac->ParamExp->Next;
|
||||||
|
@ -660,7 +662,13 @@ ExpandParam:
|
||||||
if (Mac->Exp) {
|
if (Mac->Exp) {
|
||||||
|
|
||||||
/* Use next macro token */
|
/* Use next macro token */
|
||||||
TokSet (Mac->Exp, Mac->LISlot);
|
TokSet (Mac->Exp);
|
||||||
|
|
||||||
|
/* Create new line info for this token */
|
||||||
|
if (Mac->LI) {
|
||||||
|
EndLine (Mac->LI);
|
||||||
|
}
|
||||||
|
Mac->LI = StartLine (&CurTok.Pos, LI_TYPE_MACRO, MacExpansions);
|
||||||
|
|
||||||
/* Set pointer to next token */
|
/* Set pointer to next token */
|
||||||
Mac->Exp = Mac->Exp->Next;
|
Mac->Exp = Mac->Exp->Next;
|
||||||
|
@ -723,7 +731,7 @@ ExpandParam:
|
||||||
if (Mac->Final) {
|
if (Mac->Final) {
|
||||||
|
|
||||||
/* Set the final token and remove it */
|
/* Set the final token and remove it */
|
||||||
TokSet (Mac->Final, LI_SLOT_INV);
|
TokSet (Mac->Final);
|
||||||
FreeTokNode (Mac->Final);
|
FreeTokNode (Mac->Final);
|
||||||
Mac->Final = 0;
|
Mac->Final = 0;
|
||||||
|
|
||||||
|
|
|
@ -1036,15 +1036,15 @@ int main (int argc, char* argv [])
|
||||||
CheckAssertions ();
|
CheckAssertions ();
|
||||||
}
|
}
|
||||||
|
|
||||||
/* If we didn't have an errors, index the line infos */
|
|
||||||
MakeLineInfoIndex ();
|
|
||||||
|
|
||||||
/* Dump the data */
|
/* Dump the data */
|
||||||
if (Verbosity >= 2) {
|
if (Verbosity >= 2) {
|
||||||
SymDump (stdout);
|
SymDump (stdout);
|
||||||
SegDump ();
|
SegDump ();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* If we didn't have an errors, finish off the line infos */
|
||||||
|
DoneLineInfo ();
|
||||||
|
|
||||||
/* If we didn't have any errors, create the object, listing and
|
/* If we didn't have any errors, create the object, listing and
|
||||||
* dependency files
|
* dependency files
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -122,8 +122,8 @@ struct CharSource {
|
||||||
|
|
||||||
/* Current input variables */
|
/* Current input variables */
|
||||||
static CharSource* Source = 0; /* Current char source */
|
static CharSource* Source = 0; /* Current char source */
|
||||||
static unsigned FCount = 0; /* Count of input files */
|
static unsigned FCount = 0; /* Count of input files */
|
||||||
static int C = 0; /* Current input character */
|
static int C = 0; /* Current input character */
|
||||||
|
|
||||||
/* Force end of assembly */
|
/* Force end of assembly */
|
||||||
int ForcedEnd = 0;
|
int ForcedEnd = 0;
|
||||||
|
@ -818,7 +818,7 @@ static int Sweet16Reg (const StrBuf* Id)
|
||||||
void NextRawTok (void)
|
void NextRawTok (void)
|
||||||
/* Read the next raw token from the input stream */
|
/* Read the next raw token from the input stream */
|
||||||
{
|
{
|
||||||
Macro* M;
|
Macro* M;
|
||||||
|
|
||||||
/* If we've a forced end of assembly, don't read further */
|
/* If we've a forced end of assembly, don't read further */
|
||||||
if (ForcedEnd) {
|
if (ForcedEnd) {
|
||||||
|
@ -831,7 +831,7 @@ Restart:
|
||||||
if (InputFromStack ()) {
|
if (InputFromStack ()) {
|
||||||
if (CurTok.Tok == TOK_IDENT && (M = FindDefine (&CurTok.SVal)) != 0) {
|
if (CurTok.Tok == TOK_IDENT && (M = FindDefine (&CurTok.SVal)) != 0) {
|
||||||
/* This is a define style macro - expand it */
|
/* This is a define style macro - expand it */
|
||||||
MacExpandStart (M);
|
MacExpandStart (M);
|
||||||
goto Restart;
|
goto Restart;
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
|
@ -852,7 +852,7 @@ Again:
|
||||||
SB_Clear (&CurTok.SVal);
|
SB_Clear (&CurTok.SVal);
|
||||||
|
|
||||||
/* Generate line info for the current token */
|
/* Generate line info for the current token */
|
||||||
GenLineInfo (LI_SLOT_ASM, &CurTok.Pos);
|
NewAsmLine ();
|
||||||
|
|
||||||
/* Hex number or PC symbol? */
|
/* Hex number or PC symbol? */
|
||||||
if (C == '$') {
|
if (C == '$') {
|
||||||
|
@ -901,7 +901,7 @@ Again:
|
||||||
CurTok.IVal = 0;
|
CurTok.IVal = 0;
|
||||||
}
|
}
|
||||||
CurTok.IVal = (CurTok.IVal << 1) + DigitVal (C);
|
CurTok.IVal = (CurTok.IVal << 1) + DigitVal (C);
|
||||||
NextChar ();
|
NextChar ();
|
||||||
}
|
}
|
||||||
|
|
||||||
/* This is an integer constant */
|
/* This is an integer constant */
|
||||||
|
@ -1097,7 +1097,7 @@ Again:
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
} else if (CPU == CPU_SWEET16 &&
|
} else if (CPU == CPU_SWEET16 &&
|
||||||
|
@ -1195,7 +1195,7 @@ CharAgain:
|
||||||
NextChar ();
|
NextChar ();
|
||||||
switch (C) {
|
switch (C) {
|
||||||
|
|
||||||
case ':':
|
case ':':
|
||||||
NextChar ();
|
NextChar ();
|
||||||
CurTok.Tok = TOK_NAMESPACE;
|
CurTok.Tok = TOK_NAMESPACE;
|
||||||
break;
|
break;
|
||||||
|
@ -1244,7 +1244,7 @@ CharAgain:
|
||||||
case '#':
|
case '#':
|
||||||
NextChar ();
|
NextChar ();
|
||||||
CurTok.Tok = TOK_HASH;
|
CurTok.Tok = TOK_HASH;
|
||||||
return;
|
return;
|
||||||
|
|
||||||
case '(':
|
case '(':
|
||||||
NextChar ();
|
NextChar ();
|
||||||
|
@ -1342,7 +1342,7 @@ CharAgain:
|
||||||
}
|
}
|
||||||
CurTok.IVal = C;
|
CurTok.IVal = C;
|
||||||
CurTok.Tok = TOK_CHARCON;
|
CurTok.Tok = TOK_CHARCON;
|
||||||
NextChar ();
|
NextChar ();
|
||||||
if (C != '\'') {
|
if (C != '\'') {
|
||||||
if (!MissingCharTerm) {
|
if (!MissingCharTerm) {
|
||||||
Error ("Illegal character constant");
|
Error ("Illegal character constant");
|
||||||
|
|
|
@ -165,7 +165,9 @@ void WriteSpans (const Collection* Spans)
|
||||||
/* Get next range */
|
/* Get next range */
|
||||||
const Span* S = CollConstAt (Spans, I);
|
const Span* S = CollConstAt (Spans, I);
|
||||||
|
|
||||||
/* Write data for th span We will write the size instead of the end
|
CHECK (S->End > S->Start);
|
||||||
|
|
||||||
|
/* Write data for the span We will write the size instead of the end
|
||||||
* offset to save some bytes, since most spans are expected to be
|
* offset to save some bytes, since most spans are expected to be
|
||||||
* rather small.
|
* rather small.
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -82,20 +82,12 @@ void FreeTokNode (TokNode* N)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void TokSet (TokNode* N, int LineInfoSlot)
|
void TokSet (TokNode* N)
|
||||||
/* Set the scanner token from the given token node. If the given line info
|
/* Set the scanner token from the given token node. */
|
||||||
* slot is not LI_SLOT_INV, it is used to store the position of the token fed
|
|
||||||
* into the scanner.
|
|
||||||
*/
|
|
||||||
{
|
{
|
||||||
/* Set the values */
|
/* Set the values */
|
||||||
CopyToken (&CurTok, &N->T);
|
CopyToken (&CurTok, &N->T);
|
||||||
SB_Terminate (&CurTok.SVal);
|
SB_Terminate (&CurTok.SVal);
|
||||||
|
|
||||||
/* Set the position if the slot is not invald */
|
|
||||||
if (LineInfoSlot != LI_SLOT_INV) {
|
|
||||||
GenLineInfo (LineInfoSlot, &CurTok.Pos);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -227,7 +219,10 @@ static int ReplayTokList (void* List)
|
||||||
CHECK (L->Last != 0);
|
CHECK (L->Last != 0);
|
||||||
|
|
||||||
/* Set the next token from the list */
|
/* Set the next token from the list */
|
||||||
TokSet (L->Last, LI_SLOT_ASM);
|
TokSet (L->Last);
|
||||||
|
|
||||||
|
/* Set the line info for the new token */
|
||||||
|
NewAsmLine ();
|
||||||
|
|
||||||
/* If a check function is defined, call it, so it may look at the token
|
/* If a check function is defined, call it, so it may look at the token
|
||||||
* just set and changed it as apropriate.
|
* just set and changed it as apropriate.
|
||||||
|
|
|
@ -95,11 +95,8 @@ TokNode* NewTokNode (void);
|
||||||
void FreeTokNode (TokNode* N);
|
void FreeTokNode (TokNode* N);
|
||||||
/* Free the given token node */
|
/* Free the given token node */
|
||||||
|
|
||||||
void TokSet (TokNode* N, int LineInfoSlot);
|
void TokSet (TokNode* N);
|
||||||
/* Set the scanner token from the given token node. If the given line info
|
/* Set the scanner token from the given token node. */
|
||||||
* slot is not LI_SLOT_INV, it is used to store the position of the token fed
|
|
||||||
* into the scanner.
|
|
||||||
*/
|
|
||||||
|
|
||||||
enum TC TokCmp (const TokNode* N);
|
enum TC TokCmp (const TokNode* N);
|
||||||
/* Compare the token given as parameter against the current token */
|
/* Compare the token given as parameter against the current token */
|
||||||
|
|
Loading…
Reference in New Issue
Block a user