From: uz Date: Mon, 24 Jan 2011 22:38:22 +0000 (+0000) Subject: Started to generalize line info handling. Remove separate FilePos fields and X-Git-Tag: V2.13.3~546 X-Git-Url: https://git.sur5r.net/?a=commitdiff_plain;h=06e315203530d1ed4f7a426875d76aa9bd9fa148;p=cc65 Started to generalize line info handling. Remove separate FilePos fields and try to manage all and everything with LineInfos. git-svn-id: svn://svn.cc65.org/cc65/trunk@4914 b7a2c559-68d2-44c3-8de9-860c34a00d81 --- diff --git a/src/ca65/asserts.c b/src/ca65/asserts.c index 126231c06..84b2621c7 100644 --- a/src/ca65/asserts.c +++ b/src/ca65/asserts.c @@ -41,8 +41,8 @@ #include "asserts.h" #include "error.h" #include "expr.h" +#include "lineinfo.h" #include "objfile.h" -#include "scanner.h" #include "spool.h" @@ -59,7 +59,7 @@ struct Assertion { ExprNode* Expr; /* Expression to evaluate */ AssertAction Action; /* Action to take */ unsigned Msg; /* Message to print (if any) */ - FilePos Pos; /* File position of assertion */ + Collection LI; /* Line infos for the assertion */ }; /* Collection with all assertions for a module */ @@ -83,7 +83,8 @@ static Assertion* NewAssertion (ExprNode* Expr, AssertAction Action, unsigned Ms A->Expr = Expr; A->Action = Action; A->Msg = Msg; - A->Pos = CurTok.Pos; + A->LI = EmptyCollection; + GetFullLineInfo (&A->LI); /* Return the new struct */ return A; @@ -128,11 +129,11 @@ void CheckAssertions (void) switch (A->Action) { case ASSERT_ACT_WARN: - PWarning (&A->Pos, 0, "%s", Msg); + LIWarning (&A->LI, 0, "%s", Msg); break; case ASSERT_ACT_ERROR: - PError (&A->Pos, "%s", Msg); + LIError (&A->LI, "%s", Msg); break; default: @@ -169,7 +170,7 @@ void WriteAssertions (void) WriteExpr (A->Expr); ObjWriteVar ((unsigned) A->Action); ObjWriteVar (A->Msg); - ObjWritePos (&A->Pos); + WriteLineInfo (&A->LI); } /* Done writing the assertions */ @@ -179,4 +180,4 @@ void WriteAssertions (void) - + diff --git a/src/ca65/dbginfo.c b/src/ca65/dbginfo.c index fc80539b4..15745b3fd 100644 --- a/src/ca65/dbginfo.c +++ b/src/ca65/dbginfo.c @@ -48,6 +48,17 @@ +/*****************************************************************************/ +/* Data */ +/*****************************************************************************/ + + + +/* The line info slot used */ +static unsigned LineInfoSlot; + + + /*****************************************************************************/ /* Code */ /*****************************************************************************/ @@ -103,7 +114,7 @@ void DbgInfoLine (void) * follow, the last line info is terminated. */ if (CurTok.Tok == TOK_SEP) { - ClearLineInfo (); + ClearLineInfo (LineInfoSlot); return; } @@ -133,7 +144,7 @@ void DbgInfoLine (void) } /* Remember the line info */ - GenLineInfo (Index, LineNum, 0); + GenLineInfo (LineInfoSlot, Index, LineNum, 0); } @@ -146,5 +157,3 @@ void DbgInfoSym (void) - - diff --git a/src/ca65/dbginfo.h b/src/ca65/dbginfo.h index 9f0ce3ed5..30fd7ed56 100644 --- a/src/ca65/dbginfo.h +++ b/src/ca65/dbginfo.h @@ -6,10 +6,10 @@ /* */ /* */ /* */ -/* (C) 2000-2001 Ullrich von Bassewitz */ -/* Wacholderweg 14 */ -/* D-70597 Stuttgart */ -/* EMail: uz@cc65.org */ +/* (C) 2000-2011, Ullrich von Bassewitz */ +/* Roemerstrasse 52 */ +/* D-70794 Filderstadt */ +/* EMail: uz@cc65.org */ /* */ /* */ /* This software is provided 'as-is', without any expressed or implied */ diff --git a/src/ca65/error.c b/src/ca65/error.c index 9c4ce1ede..67bf29092 100644 --- a/src/ca65/error.c +++ b/src/ca65/error.c @@ -43,6 +43,7 @@ /* ca65 */ #include "error.h" #include "filetab.h" +#include "lineinfo.h" #include "nexttok.h" @@ -62,6 +63,32 @@ unsigned WarningCount = 0; +/*****************************************************************************/ +/* Helper functions */ +/*****************************************************************************/ + + + +static int FindAsmEntry (const Collection* LineInfos) +/* Return the last entry of type LI_TYPE_ASM in the given line infos. If none + * was found, return -1. + */ +{ + unsigned I = CollCount (LineInfos); + while (I > 0) { + const LineInfo* LI = CollConstAt (LineInfos, --I); + if ((LI->Type & LI_MASK_TYPE) == LI_TYPE_ASM) { + /* Found */ + return (int) I; + } + } + + /* Not found */ + return -1; +} + + + /*****************************************************************************/ /* Warnings */ /*****************************************************************************/ @@ -111,6 +138,29 @@ void PWarning (const FilePos* Pos, unsigned Level, const char* Format, ...) +void LIWarning (const Collection* LineInfos, unsigned Level, const char* Format, ...) +/* Print warning message using the given line infos */ +{ + const LineInfo* LI; + va_list ap; + + /* Search backwards in LI for the first entry of type LI_TYPE_ASM. */ + int I = FindAsmEntry (LineInfos); + + /* We must have such an entry */ + CHECK (I >= 0); + + /* Get the position for this entry */ + LI = CollConstAt (LineInfos, I); + + /* Output a warning for this position */ + va_start (ap, Format); + WarningMsg (&LI->Pos, Level, Format, ap); + va_end (ap); +} + + + /*****************************************************************************/ /* Errors */ /*****************************************************************************/ @@ -157,6 +207,29 @@ void PError (const FilePos* Pos, const char* Format, ...) +void LIError (const Collection* LineInfos, const char* Format, ...) +/* Print an error message using the given line infos. */ +{ + const LineInfo* LI; + va_list ap; + + /* Search backwards in LI for the first entry of type LI_TYPE_ASM. */ + int I = FindAsmEntry (LineInfos); + + /* We must have such an entry */ + CHECK (I >= 0); + + /* Get the position for this entry */ + LI = CollConstAt (LineInfos, I); + + /* Output an error for this position */ + va_start (ap, Format); + ErrorMsg (&LI->Pos, Format, ap); + va_end (ap); +} + + + void ErrorSkip (const char* Format, ...) /* Print an error message and skip the rest of the line */ { diff --git a/src/ca65/error.h b/src/ca65/error.h index b14b471bd..de0e53ac5 100644 --- a/src/ca65/error.h +++ b/src/ca65/error.h @@ -6,10 +6,10 @@ /* */ /* */ /* */ -/* (C) 1998-2008 Ullrich von Bassewitz */ -/* Roemerstrasse 52 */ -/* D-70794 Filderstadt */ -/* EMail: uz@cc65.org */ +/* (C) 1998-2011, Ullrich von Bassewitz */ +/* Roemerstrasse 52 */ +/* D-70794 Filderstadt */ +/* EMail: uz@cc65.org */ /* */ /* */ /* This software is provided 'as-is', without any expressed or implied */ @@ -40,12 +40,13 @@ /* common */ #include "attrib.h" +#include "coll.h" #include "filepos.h" /*****************************************************************************/ -/* Data */ +/* Data */ /*****************************************************************************/ @@ -71,12 +72,18 @@ void Warning (unsigned Level, const char* Format, ...) attribute ((format (print void PWarning (const FilePos* Pos, unsigned Level, const char* Format, ...) attribute ((format (printf, 3, 4))); /* Print warning message giving an explicit file and position. */ +void LIWarning (const Collection* LineInfos, unsigned Level, const char* Format, ...) attribute ((format (printf, 3, 4))); +/* Print warning message using the given line infos */ + void Error (const char* Format, ...) attribute ((format (printf, 1, 2))); /* Print an error message */ void PError (const FilePos* Pos, const char* Format, ...) attribute ((format (printf, 2, 3))); /* Print an error message giving an explicit file and position. */ +void LIError (const Collection* LineInfos, const char* Format, ...) attribute ((format (printf, 2, 3))); +/* Print an error message using the given line infos. */ + void ErrorSkip (const char* Format, ...) attribute ((format (printf, 1, 2))); /* Print an error message and skip the rest of the line */ diff --git a/src/ca65/fragment.c b/src/ca65/fragment.c index 6ee4dad8b..059371e77 100644 --- a/src/ca65/fragment.c +++ b/src/ca65/fragment.c @@ -38,8 +38,6 @@ /* ca65 */ #include "fragment.h" -#include "lineinfo.h" -#include "scanner.h" @@ -60,8 +58,8 @@ Fragment* NewFragment (unsigned char Type, unsigned short Len) /* Initialize it */ F->Next = 0; F->LineList = 0; - F->Pos = CurTok.Pos; - F->LI = UseLineInfo (CurLineInfo); + F->LI = EmptyCollection; + GetFullLineInfo (&F->LI); F->Len = Len; F->Type = Type; @@ -71,4 +69,3 @@ Fragment* NewFragment (unsigned char Type, unsigned short Len) - diff --git a/src/ca65/fragment.h b/src/ca65/fragment.h index 863b4740c..2db86f48a 100644 --- a/src/ca65/fragment.h +++ b/src/ca65/fragment.h @@ -6,10 +6,10 @@ /* */ /* */ /* */ -/* (C) 1998-2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ -/* D-70794 Filderstadt */ -/* EMail: uz@cc65.org */ +/* (C) 1998-2011, Ullrich von Bassewitz */ +/* Roemerstrasse 52 */ +/* D-70794 Filderstadt */ +/* EMail: uz@cc65.org */ /* */ /* */ /* This software is provided 'as-is', without any expressed or implied */ @@ -40,27 +40,29 @@ /* common */ #include "exprdefs.h" -#include "filepos.h" +#include "coll.h" + +/* ca65 */ +#include "lineinfo.h" /*****************************************************************************/ -/* struct Fragment */ +/* struct Fragment */ /*****************************************************************************/ typedef struct Fragment Fragment; struct Fragment { - Fragment* Next; /* Pointer to next fragment in segment */ - Fragment* LineList; /* List of fragments for one src line */ - FilePos Pos; /* File position for this fragment */ - struct LineInfo* LI; /* Extra line info */ - unsigned short Len; /* Length for this fragment */ - unsigned char Type; /* Fragment type */ + Fragment* Next; /* Pointer to next fragment in segment */ + Fragment* LineList; /* List of fragments for one src line */ + Collection LI; /* Line info for this fragment */ + unsigned short Len; /* Length for this fragment */ + unsigned char Type; /* Fragment type */ union { - unsigned char Data[4]; /* Literal values */ - ExprNode* Expr; /* Expression */ + unsigned char Data[4]; /* Literal values */ + ExprNode* Expr; /* Expression */ } V; }; diff --git a/src/ca65/lineinfo.c b/src/ca65/lineinfo.c index 2e674b719..92d7612a5 100644 --- a/src/ca65/lineinfo.c +++ b/src/ca65/lineinfo.c @@ -43,38 +43,57 @@ +#include +#include + /* common */ #include "coll.h" #include "xmalloc.h" /* ca65 */ -#include "objfile.h" +#include "global.h" #include "lineinfo.h" +#include "objfile.h" /*****************************************************************************/ -/* Data */ +/* Data */ /*****************************************************************************/ +/* An invalid line info index */ +#define INV_LINEINFO_INDEX UINT_MAX + /* Collection containing all line infos */ -Collection LineInfoColl = STATIC_COLLECTION_INITIALIZER; -unsigned LineInfoValid = 0; /* Valid, that is, used entries */ +static Collection LineInfoColl = STATIC_COLLECTION_INITIALIZER; -/* Static pointer to last line info or NULL if not active */ -LineInfo* CurLineInfo = 0; +/* 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 */ +static LineInfoSlot* CurLineInfo; +static unsigned AllocatedSlots; +static unsigned UsedSlots; /*****************************************************************************/ -/* Code */ +/* struct LineInfo */ /*****************************************************************************/ -static LineInfo* NewLineInfo (unsigned File, unsigned long Line, unsigned Col) +static LineInfo* NewLineInfo (unsigned Type, unsigned File, + unsigned long Line, unsigned Col) /* Create and return a new line info. Usage will be zero. */ { /* Allocate memory */ @@ -82,13 +101,11 @@ static LineInfo* NewLineInfo (unsigned File, unsigned long Line, unsigned Col) /* Initialize the fields */ LI->Usage = 0; - LI->Index = 0; /* Currently invalid */ + LI->Type = Type; + LI->Index = INV_LINEINFO_INDEX; + LI->Pos.Name = File; LI->Pos.Line = Line; LI->Pos.Col = Col; - LI->Pos.Name = File; - - /* Insert this structure into the collection */ - CollAppend (&LineInfoColl, LI); /* Return the new struct */ return LI; @@ -96,41 +113,188 @@ static LineInfo* NewLineInfo (unsigned File, unsigned long Line, unsigned Col) -LineInfo* UseLineInfo (LineInfo* LI) -/* Increase the reference count of the given line info and return it. The - * function will gracefully accept NULL pointers and do nothing in this case. +static void FreeLineInfo (LineInfo* LI) +/* "Free" line info. If the usage counter is non zero, move it to the + * collection that contains all line infos, otherwise delete it. + * The function handles a NULL pointer transparently. */ { if (LI) { - if (LI->Usage++ == 0) { - /* One more valid line info */ - ++LineInfoValid; - } + if (LI->Usage > 0) { + CollAppend (&LineInfoColl, LI); + } else { + xfree (LI); + } } - return LI; } -void GenLineInfo (unsigned FileIndex, unsigned long LineNum, unsigned ColNum) -/* Generate a new line info */ +/*****************************************************************************/ +/* Code */ +/*****************************************************************************/ + + + +void InitLineInfo (void) +/* Initialize the line infos */ +{ + /* Allocate 8 slots */ + AllocatedSlots = 8; + CurLineInfo = xmalloc (AllocatedSlots * sizeof (LineInfoSlot)); + + /* Initalize the predefined slots */ + UsedSlots = 2; + CurLineInfo[LI_SLOT_ASM].Type = LI_TYPE_ASM; + CurLineInfo[LI_SLOT_ASM].Info = 0; + CurLineInfo[LI_SLOT_EXT].Type = LI_TYPE_EXT; + CurLineInfo[LI_SLOT_EXT].Info = 0; +} + + + +unsigned AllocLineInfoSlot (unsigned Type) +/* Allocate a line info slot of the given type and return the slot index */ +{ + /* Grow the array if necessary */ + if (UsedSlots >= AllocatedSlots) { + LineInfoSlot* NewLineInfo; + AllocatedSlots *= 2; + NewLineInfo = xmalloc (AllocatedSlots * sizeof (LineInfoSlot)); + memcpy (NewLineInfo, CurLineInfo, UsedSlots * sizeof (LineInfoSlot)); + xfree (CurLineInfo); + CurLineInfo = NewLineInfo; + } + + /* Array is now big enough, add the new data */ + CurLineInfo[UsedSlots].Type = Type; + CurLineInfo[UsedSlots].Info = 0; + + /* Increment the count and return the index of the new slot */ + return UsedSlots++; +} + + + +void FreeLineInfoSlot (unsigned Slot) +/* Free the line info in the given slot. Note: Alloc/Free must be used in + * FIFO order. + */ +{ + /* Check the parameter */ + PRECONDITION (Slot == UsedSlots - 1); + + /* Free the last entry */ + FreeLineInfo (CurLineInfo[Slot].Info); + --UsedSlots; +} + + + +void GenLineInfo (unsigned Slot, unsigned File, unsigned long Line, unsigned Col) +/* Generate a new line info in the given slot */ +{ + /* Get a pointer to the slot */ + LineInfoSlot* S = CurLineInfo + Slot; + + /* Check if we already have data */ + if (S->Info) { + /* Generate new data only if it is different from the existing. */ + if (S->Info->Pos.Col == Col && + S->Info->Pos.Line == Line && + S->Info->Pos.Name == File) { + /* Already there */ + return; + } + + /* We have data, but it's not identical. If it is in use, copy it to + * line info collection, otherwise delete it. + */ + FreeLineInfo (S->Info); + + } + + /* Allocate new data */ + S->Info = NewLineInfo (S->Type, File, Line, Col); +} + + + +void ClearLineInfo (unsigned Slot) +/* Clear the line info in the given slot */ +{ + /* Get a pointer to the slot */ + LineInfoSlot* S = CurLineInfo + Slot; + + /* Free the struct and zero the pointer */ + FreeLineInfo (S->Info); + S->Info = 0; +} + + + +LineInfo* GetLineInfo (unsigned Slot) +/* Get the line info from the given slot */ { - /* Create a new line info and make it current */ - CurLineInfo = NewLineInfo (FileIndex, LineNum, ColNum); + PRECONDITION (Slot < UsedSlots); + return CurLineInfo[Slot].Info; +} + + + +void GetFullLineInfo (Collection* LineInfos) +/* Return full line infos, that is line infos for all slots in LineInfos. The + * function does also increase the usage counter for all line infos returned. + */ +{ + unsigned I; + + /* Copy all valid line infos to the collection */ + for (I = 0; I < UsedSlots; ++I) { + + /* Get the slot */ + LineInfoSlot* S = CurLineInfo + I; + + /* Ignore empty slots */ + if (S->Info) { + ++S->Info->Usage; + CollAppend (LineInfos, S->Info); + } + } +} + + + +LineInfo* UseLineInfo (LineInfo* LI) +/* Increase 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 (LI) { + ++LI->Usage; + } + return LI; } -void ClearLineInfo (void) -/* Clear the current line info */ +LineInfo* ReleaseLineInfo (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. + */ { - CurLineInfo = 0; + if (LI) { + /* Cannot decrease below zero */ + CHECK (LI->Usage != 0); + --LI->Usage; + } + return LI; } static int CmpLineInfo (void* Data attribute ((unused)), - const void* LI1_, const void* LI2_) + const void* LI1_, const void* LI2_) /* Compare function for the sort */ { /* Cast the pointers */ @@ -138,21 +302,11 @@ static int CmpLineInfo (void* Data attribute ((unused)), const LineInfo* LI2 = LI2_; /* Unreferenced line infos are always larger, otherwise sort by file, - * then by line. + * then by line, then by column. */ if ((LI1->Usage == 0) == (LI2->Usage == 0)) { /* Both are either referenced or unreferenced */ - if (LI1->Pos.Name< LI2->Pos.Name) { - return -1; - } else if (LI1->Pos.Name > LI2->Pos.Name) { - return 1; - } else if (LI1->Pos.Line < LI2->Pos.Line) { - return -1; - } else if (LI1->Pos.Line > LI2->Pos.Line) { - return 1; - } else { - return 0; - } + return CompareFilePos (&LI1->Pos, &LI2->Pos); } else { if (LI1->Usage > 0) { return -1; @@ -164,25 +318,54 @@ static int CmpLineInfo (void* Data attribute ((unused)), +void WriteLineInfo (const Collection* LineInfos) +/* Write a list of line infos to the object file. MakeLineInfoIndex has to + * be called before! + */ +{ + unsigned I; + + /* Write the count */ + ObjWriteVar (CollCount (LineInfos)); + + /* Write the line info indices */ + for (I = 0; I < CollCount (LineInfos); ++I) { + ObjWriteVar (((const LineInfo*) CollConstAt (LineInfos, I))->Index); + } +} + + + void MakeLineInfoIndex (void) -/* Sort the line infos and drop all unreferenced ones */ +/* Index the line infos */ { unsigned I; /* Sort the collection */ CollSort (&LineInfoColl, CmpLineInfo, 0); - /* Walk over the list and index the line infos. */ - for (I = 0; I < LineInfoValid; ++I) { + /* 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); - LI->Index = 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; } } -void WriteLineInfo (void) +void WriteLineInfos (void) /* Write a list of all line infos to the object file. */ { /* Tell the object file module that we're about to write line infos */ @@ -194,15 +377,12 @@ void WriteLineInfo (void) unsigned I; /* Write the line info count to the list */ - ObjWriteVar (LineInfoValid); + ObjWriteVar (UsedLineInfoCount); - /* Walk through list and write all line infos that have references. - * Because of the sort, this are exactly the first LineInfoValid - * ones. - */ - for (I = 0; I < LineInfoValid; ++I) { + /* Walk over the list and write all line infos */ + for (I = 0; I < UsedLineInfoCount; ++I) { /* Get a pointer to this line info */ - LineInfo* LI = CollAtUnchecked (&LineInfoColl, I); + LineInfo* LI = CollAt (&LineInfoColl, I); /* Write the source file position */ ObjWritePos (&LI->Pos); } diff --git a/src/ca65/lineinfo.h b/src/ca65/lineinfo.h index 0d1ca495d..ec654118e 100644 --- a/src/ca65/lineinfo.h +++ b/src/ca65/lineinfo.h @@ -52,34 +52,46 @@ #include "coll.h" #include "filepos.h" -/* ca65 */ -#include "global.h" - /*****************************************************************************/ -/* Data */ +/* Data */ /*****************************************************************************/ +/* Predefined line info slots. These are allocated when initializing the + * 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_ASM = 0, /* Normal assembler source */ + LI_SLOT_EXT = 1, /* Externally supplied line info */ +}; + +/* Types of line infos. The low byte may be used for some sort of depth + * counter. + */ +enum { + LI_MASK_COUNT = 0x00FF, /* Mask to extract the count */ + + LI_TYPE_EXT = 0x0100, /* Externally supplied line info */ + LI_TYPE_ASM = 0x0200, /* Normal assembler source */ + LI_TYPE_MACRO = 0x0300, /* Macro expansion */ + LI_MASK_TYPE = 0x7F00, /* Mask to extract the type */ +}; + /* The LineInfo structure is shared between several fragments, so we need a * reference counter. */ typedef struct LineInfo LineInfo; struct LineInfo { - unsigned Usage; /* Usage counter */ - unsigned Index; /* Index */ - FilePos Pos; /* File position */ + unsigned Usage; /* Usage counter */ + unsigned Type; /* Type of line info */ + unsigned Index; /* Index */ + FilePos Pos; /* File position */ }; -/* Collection containing all line infos */ -extern Collection LineInfoColl; -extern unsigned LineInfoValid; /* Valid, that is, used entries */ - -/* Global pointer to last line info or NULL if not active */ -extern LineInfo* CurLineInfo; - /*****************************************************************************/ @@ -88,23 +100,50 @@ extern LineInfo* CurLineInfo; +void InitLineInfo (void); +/* Initialize the line infos */ + +unsigned AllocLineInfoSlot (unsigned Type); +/* Allocate a line info slot of the given type and return the slot index */ + +void FreeLineInfoSlot (unsigned Slot); +/* Free the line info in the given slot. Note: Alloc/Free must be used in + * FIFO order. + */ + +void GenLineInfo (unsigned Slot, unsigned File, unsigned long Line, unsigned Col); +/* Generate a new line info in the given slot */ + +void ClearLineInfo (unsigned Slot); +/* Clear the line info in the given slot */ + +LineInfo* GetLineInfo (unsigned Slot); +/* Get the line info from the given slot */ + +void GetFullLineInfo (Collection* LineInfos); +/* Return full line infos, that is line infos for all slots in LineInfos. The + * function does also increase the usage counter for all line infos returned. + */ + LineInfo* UseLineInfo (LineInfo* LI); /* Increase the reference count of the given line info and return it. The * function will gracefully accept NULL pointers and do nothing in this case. */ -void GenLineInfo (unsigned FileIndex, unsigned long LineNum, unsigned ColNum); -/* Generate a new line info */ +LineInfo* ReleaseLineInfo (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. + */ -void ClearLineInfo (void); -/* Clear the current line info */ +void WriteLineInfo (const Collection* LineInfos); +/* Write a list of line infos to the object file. MakeLineInfoIndex has to + * be called before! + */ void MakeLineInfoIndex (void); -/* Walk over the line info list and make an index of all entries ignoring - * those with a usage count of zero. - */ +/* Index the line infos */ -void WriteLineInfo (void); +void WriteLineInfos (void); /* Write a list of all line infos to the object file. */ diff --git a/src/ca65/main.c b/src/ca65/main.c index 53bd5be48..a5db62559 100644 --- a/src/ca65/main.c +++ b/src/ca65/main.c @@ -805,7 +805,7 @@ static void CreateObjFile (void) WriteDbgSyms (); /* Write line infos if requested */ - WriteLineInfo (); + WriteLineInfos (); /* Write the string pool */ WriteStrPool (); @@ -902,7 +902,7 @@ int main (int argc, char* argv []) break; case 'o': - OutFile = GetArg (&I, 2); + OutFile = GetArg (&I, 2); break; case 's': @@ -926,7 +926,7 @@ int main (int argc, char* argv []) break; case 'U': - OptAutoImport (Arg, 0); + OptAutoImport (Arg, 0); break; case 'V': @@ -980,6 +980,9 @@ int main (int argc, char* argv []) /* Initialize the segments */ InitSegments (); + /* Initialize the line infos */ + InitLineInfo (); + /* Initialize the scanner, open the input file */ InitScanner (InFile); diff --git a/src/ca65/segment.c b/src/ca65/segment.c index 0f07ce52b..b94123058 100644 --- a/src/ca65/segment.c +++ b/src/ca65/segment.c @@ -371,24 +371,24 @@ void SegCheck (void) if (Abs) { /* Absolute value */ if (Val > 255) { - PError (&F->Pos, "Range error (%ld not in [0..255])", Val); + LIError (&F->LI, "Range error (%ld not in [0..255])", Val); } } else { /* PC relative value */ if (Val < -128 || Val > 127) { - PError (&F->Pos, "Range error (%ld not in [-128..127])", Val); + LIError (&F->LI, "Range error (%ld not in [-128..127])", Val); } } } else if (F->Len == 2) { if (Abs) { /* Absolute value */ if (Val > 65535) { - PError (&F->Pos, "Range error (%ld not in [0..65535])", Val); + LIError (&F->LI, "Range error (%ld not in [0..65535])", Val); } } else { /* PC relative value */ if (Val < -32768 || Val > 32767) { - PError (&F->Pos, "Range error (%ld not in [-32768..32767])", Val); + LIError (&F->LI, "Range error (%ld not in [-32768..32767])", Val); } } } @@ -412,7 +412,7 @@ void SegCheck (void) if ((F->Len == 1 && ED.AddrSize > ADDR_SIZE_ZP) || (F->Len == 2 && ED.AddrSize > ADDR_SIZE_ABS) || (F->Len == 3 && ED.AddrSize > ADDR_SIZE_FAR)) { - PError (&F->Pos, "Range error"); + LIError (&F->LI, "Range error"); } } @@ -477,7 +477,6 @@ static void WriteOneSeg (Segment* Seg) /* Write one segment to the object file */ { Fragment* Frag; - unsigned LineInfoIndex; unsigned long DataSize; unsigned long EndPos; @@ -541,14 +540,8 @@ static void WriteOneSeg (Segment* Seg) } - /* Write the file position of this fragment */ - ObjWritePos (&Frag->Pos); - - /* Write extra line info for this fragment. Zero is considered - * "no line info", so add one to the value. - */ - LineInfoIndex = Frag->LI? Frag->LI->Index + 1 : 0; - ObjWriteVar (LineInfoIndex); + /* Write the line infos for this fragment */ + WriteLineInfo (&Frag->LI); /* Next fragment */ Frag = Frag->Next; @@ -620,3 +613,4 @@ void WriteSegments (void) +