1
0
mirror of https://github.com/cc65/cc65.git synced 2024-07-02 15:29:33 +00:00

Use LineInfo instead of raw FilePos objects. Most information in the object

files does now have lists of LineInfos attached. Compiles but UNTESTED!


git-svn-id: svn://svn.cc65.org/cc65/trunk@4921 b7a2c559-68d2-44c3-8de9-860c34a00d81
This commit is contained in:
uz 2011-01-26 19:42:17 +00:00
parent 25c13a4f54
commit 733e832b5d
19 changed files with 349 additions and 295 deletions

View File

@ -41,7 +41,7 @@
/* ld65 */
#include "asserts.h"
#include "error.h"
#include "expr.h"
#include "expr.h"
#include "fileio.h"
#include "lineinfo.h"
#include "objdata.h"
@ -75,30 +75,6 @@ static Collection Assertions = STATIC_COLLECTION_INITIALIZER;
static const char* GetAssertionSourceName (const Assertion* A)
/* Return the name of the source file for this assertion */
{
/* Each assertion has the basic info in line info #0 */
const LineInfo* LI = CollConstAt (&A->LineInfos, 0);
/* Return the source file name */
return GetSourceFileName (A->Obj, LI->Pos.Name);
}
static unsigned long GetAssertionSourceLine (const Assertion* A)
/* Return the source file line for this fragment */
{
/* Each assertion has the basic info in line info #0 */
const LineInfo* LI = CollConstAt (&A->LineInfos, 0);
/* Return the source file line */
return LI->Pos.Line;
}
Assertion* ReadAssertion (FILE* F, struct ObjData* O)
/* Read an assertion from the given file */
{
@ -131,6 +107,7 @@ void CheckAssertions (void)
/* Walk over all assertions */
for (I = 0; I < CollCount (&Assertions); ++I) {
const LineInfo* LI;
const char* Module;
unsigned long Line;
@ -142,9 +119,12 @@ void CheckAssertions (void)
continue;
}
/* Retrieve module name and line number */
Module = GetAssertionSourceName (A);
Line = GetAssertionSourceLine (A);
/* Retrieve the relevant line info for this assertion */
LI = CollConstAt (&A->LineInfos, 0);
/* Get file name and line number from the source */
Module = GetSourceName (LI);
Line = GetSourceLine (LI);
/* If the expression is not constant, we're not able to handle it */
if (!IsConstExpr (A->Expr)) {
@ -176,6 +156,6 @@ void CheckAssertions (void)
}
}
}

View File

@ -42,6 +42,7 @@
#include "error.h"
#include "exports.h"
#include "expr.h"
#include "lineinfo.h"
#include "scanner.h"
#include "spool.h"
@ -74,7 +75,7 @@ static ExprNode* Factor (void)
} else {
N = NewExprNode (0, EXPR_SYMBOL);
N->V.Imp = InsertImport (GenImport (Name, ADDR_SIZE_ABS));
N->V.Imp->Pos = CfgErrorPos;
CollAppend (&N->V.Imp->LineInfos, GenLineInfo (&CfgErrorPos));
}
/* Skip the symbol name */

View File

@ -128,7 +128,7 @@ typedef enum {
typedef struct CfgSymbol CfgSymbol;
struct CfgSymbol {
CfgSymType Type; /* Type of symbol */
FilePos Pos; /* Config file position */
LineInfo* LI; /* Config file position */
unsigned Name; /* Symbol name */
ExprNode* Value; /* Symbol value if any */
unsigned AddrSize; /* Address size of symbol */
@ -268,7 +268,7 @@ static CfgSymbol* NewCfgSymbol (CfgSymType Type, unsigned Name)
/* Initialize the fields */
Sym->Type = Type;
Sym->Pos = CfgErrorPos;
Sym->LI = GenLineInfo (&CfgErrorPos);
Sym->Name = Name;
Sym->Value = 0;
Sym->AddrSize = ADDR_SIZE_INVALID;
@ -341,7 +341,7 @@ static SegDesc* NewSegDesc (unsigned Name)
/* Initialize the fields */
S->Name = Name;
S->Pos = CfgErrorPos;
S->LI = GenLineInfo (&CfgErrorPos);
S->Seg = 0;
S->Attr = 0;
S->Flags = 0;
@ -767,9 +767,9 @@ static void ParseSegments (void)
* separate run and load memory areas.
*/
if ((S->Flags & SF_ALIGN_LOAD) != 0 && (S->Load == S->Run)) {
Warning ("%s(%lu): ALIGN_LOAD attribute specified, but no separate "
"LOAD and RUN memory areas assigned",
CfgGetName (), CfgErrorPos.Line);
CfgWarning (&CfgErrorPos,
"ALIGN_LOAD attribute specified, but no separate "
"LOAD and RUN memory areas assigned");
/* Remove the flag */
S->Flags &= ~SF_ALIGN_LOAD;
}
@ -778,8 +778,9 @@ static void ParseSegments (void)
* load and run memory areas, because it's is never written to disk.
*/
if ((S->Flags & SF_BSS) != 0 && (S->Load != S->Run)) {
Warning ("%s(%lu): Segment with type `bss' has both LOAD and RUN "
"memory areas assigned", CfgGetName (), CfgErrorPos.Line);
CfgWarning (&CfgErrorPos,
"Segment with type `bss' has both LOAD and RUN "
"memory areas assigned");
}
/* Don't allow read/write data to be put into a readonly area */
@ -1416,7 +1417,7 @@ static void ParseSymbols (void)
AttrCheck (AttrFlags, atType, "TYPE");
/* Create the export */
Exp = CreateExprExport (Name, Value, AddrSize);
Exp->Pos = CfgErrorPos;
CollAppend (&Exp->LineInfos, GenLineInfo (&CfgErrorPos));
break;
case CfgSymImport:
@ -1427,7 +1428,7 @@ static void ParseSymbols (void)
/* Generate the import */
Imp = InsertImport (GenImport (Name, AddrSize));
/* Remember the file position */
Imp->Pos = CfgErrorPos;
CollAppend (&Imp->LineInfos, GenLineInfo (&CfgErrorPos));
break;
case CfgSymWeak:
@ -1565,8 +1566,9 @@ static void ProcessSegments (void)
* in the segment.
*/
if ((S->Flags & SF_BSS) != 0 && S->Seg != 0 && !IsBSSType (S->Seg)) {
Warning ("Segment `%s' with type `bss' contains initialized data",
GetString (S->Name));
CfgWarning (GetSourcePos (S->LI),
"Segment `%s' with type `bss' contains initialized data",
GetString (S->Name));
}
/* If this segment does exist in any of the object files, insert the
@ -1623,7 +1625,7 @@ static void ProcessSymbols (void)
/* Check if the export symbol is also defined as an import. */
if (O65GetImport (O65FmtDesc, Sym->Name) != 0) {
CfgError (
&Sym->Pos,
GetSourcePos (Sym->LI),
"Exported o65 symbol `%s' cannot also be an o65 import",
GetString (Sym->Name)
);
@ -1635,7 +1637,7 @@ static void ProcessSymbols (void)
*/
if (O65GetExport (O65FmtDesc, Sym->Name) != 0) {
CfgError (
&Sym->Pos,
GetSourcePos (Sym->LI),
"Duplicate exported o65 symbol: `%s'",
GetString (Sym->Name)
);
@ -1649,7 +1651,7 @@ static void ProcessSymbols (void)
/* Check if the import symbol is also defined as an export. */
if (O65GetExport (O65FmtDesc, Sym->Name) != 0) {
CfgError (
&Sym->Pos,
GetSourcePos (Sym->LI),
"Imported o65 symbol `%s' cannot also be an o65 export",
GetString (Sym->Name)
);
@ -1661,7 +1663,7 @@ static void ProcessSymbols (void)
*/
if (O65GetImport (O65FmtDesc, Sym->Name) != 0) {
CfgError (
&Sym->Pos,
GetSourcePos (Sym->LI),
"Duplicate imported o65 symbol: `%s'",
GetString (Sym->Name)
);
@ -1676,7 +1678,7 @@ static void ProcessSymbols (void)
if ((E = FindExport (Sym->Name)) == 0 || IsUnresolvedExport (E)) {
/* The symbol is undefined, generate an export */
E = CreateExprExport (Sym->Name, Sym->Value, Sym->AddrSize);
E->Pos = Sym->Pos;
CollAppend (&E->LineInfos, Sym->LI);
}
break;
@ -1699,12 +1701,12 @@ static void CreateRunDefines (SegDesc* S, unsigned long SegAddr)
/* Define the run address of the segment */
SB_Printf (&Buf, "__%s_RUN__", GetString (S->Name));
E = CreateMemoryExport (GetStrBufId (&Buf), S->Run, SegAddr - S->Run->Start);
E->Pos = S->Pos;
CollAppend (&E->LineInfos, S->LI);
/* Define the size of the segment */
SB_Printf (&Buf, "__%s_SIZE__", GetString (S->Name));
E = CreateConstExport (GetStrBufId (&Buf), S->Seg->Size);
E->Pos = S->Pos;
CollAppend (&E->LineInfos, S->LI);
S->Flags |= SF_RUN_DEF;
SB_Done (&Buf);
@ -1721,7 +1723,7 @@ static void CreateLoadDefines (SegDesc* S, unsigned long SegAddr)
/* Define the load address of the segment */
SB_Printf (&Buf, "__%s_LOAD__", GetString (S->Name));
E = CreateMemoryExport (GetStrBufId (&Buf), S->Load, SegAddr - S->Load->Start);
E->Pos = S->Pos;
CollAppend (&E->LineInfos, S->LI);
S->Flags |= SF_LOAD_DEF;
SB_Done (&Buf);
@ -1768,7 +1770,7 @@ unsigned CfgProcess (void)
* and mark the memory area as placed.
*/
if (!IsConstExpr (M->StartExpr)) {
CfgError (&M->Pos,
CfgError (GetSourcePos (M->LI),
"Start address of memory area `%s' is not constant",
GetString (M->Name));
}
@ -1786,14 +1788,14 @@ unsigned CfgProcess (void)
/* Define the start of the memory area */
SB_Printf (&Buf, "__%s_START__", GetString (M->Name));
E = CreateMemoryExport (GetStrBufId (&Buf), M, 0);
E->Pos = M->Pos;
CollAppend (&E->LineInfos, M->LI);
SB_Done (&Buf);
}
/* Resolve the size expression */
if (!IsConstExpr (M->SizeExpr)) {
CfgError (&M->Pos,
CfgError (GetSourcePos (M->LI),
"Size of memory area `%s' is not constant",
GetString (M->Name));
}
@ -1827,12 +1829,12 @@ unsigned CfgProcess (void)
if (Addr > NewAddr) {
/* Offset already too large */
if (S->Flags & SF_OFFSET) {
CfgError (&M->Pos,
CfgError (GetSourcePos (M->LI),
"Offset too small in `%s', segment `%s'",
GetString (M->Name),
GetString (S->Name));
} else {
CfgError (&M->Pos,
CfgError (GetSourcePos (M->LI),
"Start address too low in `%s', segment `%s'",
GetString (M->Name),
GetString (S->Name));
@ -1872,9 +1874,10 @@ unsigned CfgProcess (void)
if (M->FillLevel > M->Size && (M->Flags & MF_OVERFLOW) == 0) {
++Overflows;
M->Flags |= MF_OVERFLOW;
Warning ("Memory area overflow in `%s', segment `%s' (%lu bytes)",
GetString (M->Name), GetString (S->Name),
M->FillLevel - M->Size);
CfgWarning (GetSourcePos (M->LI),
"Memory area overflow in `%s', segment `%s' (%lu bytes)",
GetString (M->Name), GetString (S->Name),
M->FillLevel - M->Size);
}
/* If requested, define symbols for the start and size of the
@ -1902,12 +1905,12 @@ unsigned CfgProcess (void)
/* Define the size of the memory area */
SB_Printf (&Buf, "__%s_SIZE__", GetString (M->Name));
E = CreateConstExport (GetStrBufId (&Buf), M->Size);
E->Pos = M->Pos;
CollAppend (&E->LineInfos, M->LI);
/* Define the fill level of the memory area */
SB_Printf (&Buf, "__%s_LAST__", GetString (M->Name));
E = CreateMemoryExport (GetStrBufId (&Buf), M, M->FillLevel);
E->Pos = M->Pos;
CollAppend (&E->LineInfos, M->LI);
SB_Done (&Buf);
}

View File

@ -43,6 +43,7 @@
#include "filepos.h"
/* ld65 */
#include "lineinfo.h"
#include "segments.h"
@ -69,7 +70,7 @@ struct File {
typedef struct SegDesc SegDesc;
struct SegDesc {
unsigned Name; /* Index of the name */
FilePos Pos; /* Position of definition */
LineInfo* LI; /* Position of definition */
Segment* Seg; /* Pointer to segment structure */
unsigned Attr; /* Attributes for segment */
unsigned Flags; /* Set of bitmapped flags */
@ -115,7 +116,7 @@ unsigned CfgProcess (void);
void CfgWriteTarget (void);
/* Write the target file(s) */
/* End of config.h */

View File

@ -6,7 +6,7 @@
/* */
/* */
/* */
/* (C) 2001-2010, Ullrich von Bassewitz */
/* (C) 2001-2011, Ullrich von Bassewitz */
/* Roemerstrasse 52 */
/* D-70794 Filderstadt */
/* EMail: uz@cc65.org */
@ -79,7 +79,7 @@ void PrintDbgInfo (ObjData* O, FILE* F)
/* Print it */
fprintf (F,
"line\tfile=%u,line=%lu,segment=%u,range=0x%06lX-0x%06lX",
LI->File->Id, LI->Pos.Line, R->Seg->Id,
LI->File->Id, GetSourceLine (LI), R->Seg->Id,
R->Offs, R->Offs + R->Size - 1);
}

View File

@ -6,7 +6,7 @@
/* */
/* */
/* */
/* (C) 1998-2010, Ullrich von Bassewitz */
/* (C) 1998-2011, Ullrich von Bassewitz */
/* Roemerstrasse 52 */
/* D-70794 Filderstadt */
/* EMail: uz@cc65.org */
@ -47,6 +47,7 @@
#include "expr.h"
#include "fileio.h"
#include "global.h"
#include "lineinfo.h"
#include "objdata.h"
#include "spool.h"
@ -75,16 +76,17 @@ static DbgSym* NewDbgSym (unsigned char Type, unsigned char AddrSize, ObjData* O
/* Create a new DbgSym and return it */
{
/* Allocate memory */
DbgSym* D = xmalloc (sizeof (DbgSym));
DbgSym* D = xmalloc (sizeof (DbgSym));
/* Initialize the fields */
D->Next = 0;
D->Flags = 0;
D->Obj = O;
D->Expr = 0;
D->Name = 0;
D->Type = Type;
D->AddrSize = AddrSize;
D->Next = 0;
D->Flags = 0;
D->Obj = O;
D->LineInfos = EmptyCollection;
D->Expr = 0;
D->Name = 0;
D->Type = Type;
D->AddrSize = AddrSize;
/* Return the new entry */
return D;
@ -158,8 +160,8 @@ DbgSym* ReadDbgSym (FILE* F, ObjData* O)
D->Expr = LiteralExpr (Read32 (F), O);
}
/* Last is the file position where the definition was done */
ReadFilePos (F, &D->Pos);
/* Last is the list of line infos for this symbol */
ReadLineInfoList (F, O, &D->LineInfos);
/* Return the new DbgSym */
return D;

View File

@ -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 */
@ -41,8 +41,8 @@
#include <stdio.h>
/* common */
#include "coll.h"
#include "exprdefs.h"
#include "filepos.h"
/* ld65 */
#include "objdata.h"
@ -61,7 +61,7 @@ struct DbgSym {
DbgSym* Next; /* Pool linear list link */
unsigned Flags; /* Generic flags */
ObjData* Obj; /* Object file that exports the name */
FilePos Pos; /* File position of definition */
Collection LineInfos; /* Line infos of definition */
ExprNode* Expr; /* Expression (0 if not def'd) */
unsigned Name; /* Name */
unsigned char Type; /* Type of symbol */

View File

@ -6,7 +6,7 @@
/* */
/* */
/* */
/* (C) 1998-2010, Ullrich von Bassewitz */
/* (C) 1998-2011, Ullrich von Bassewitz */
/* Roemerstrasse 52 */
/* D-70794 Filderstadt */
/* EMail: uz@cc65.org */
@ -40,7 +40,6 @@
/* common */
#include "addrsize.h"
#include "check.h"
#include "coll.h"
#include "hashstr.h"
#include "symdefs.h"
#include "xmalloc.h"
@ -52,6 +51,7 @@
#include "expr.h"
#include "fileio.h"
#include "global.h"
#include "lineinfo.h"
#include "memarea.h"
#include "objdata.h"
#include "spool.h"
@ -102,16 +102,16 @@ static Import* NewImport (unsigned char AddrSize, ObjData* Obj)
/* Create a new import and initialize it */
{
/* Allocate memory */
Import* I = xmalloc (sizeof (Import));
Import* I = xmalloc (sizeof (Import));
/* Initialize the fields */
I->Next = 0;
I->Obj = Obj;
InitFilePos (&I->Pos);
I->Exp = 0;
I->Name = INVALID_STRING_ID;
I->Flags = 0;
I->AddrSize = AddrSize;
I->Next = 0;
I->Obj = Obj;
I->LineInfos = EmptyCollection;
I->Exp = 0;
I->Name = INVALID_STRING_ID;
I->Flags = 0;
I->AddrSize = AddrSize;
/* Return the new structure */
return I;
@ -128,6 +128,9 @@ void FreeImport (Import* I)
/* Safety */
PRECONDITION ((I->Flags & IMP_INLIST) == 0);
/* Free the line info collection */
DoneCollection (&I->LineInfos);
/* Free the struct */
xfree (I);
}
@ -148,8 +151,8 @@ Import* ReadImport (FILE* F, ObjData* Obj)
/* Read the name */
I->Name = MakeGlobalStringId (Obj, ReadVar (F));
/* Read the file position */
ReadFilePos (F, &I->Pos);
/* Read the line infos */
ReadLineInfoList (F, Obj, &I->LineInfos);
/* Check the address size */
if (I->AddrSize == ADDR_SIZE_DEFAULT || I->AddrSize > ADDR_SIZE_LONG) {
@ -158,10 +161,11 @@ Import* ReadImport (FILE* F, ObjData* Obj)
* invalid. Be sure not to access it in this case.
*/
if (ObjHasFiles (I->Obj)) {
const LineInfo* LI = GetImportPos (I);
Error ("Invalid import size in for `%s', imported from %s(%lu): 0x%02X",
GetString (I->Name),
GetSourceFileName (I->Obj, I->Pos.Name),
I->Pos.Line,
GetSourceName (LI),
GetSourceLine (LI),
I->AddrSize);
} else {
Error ("Invalid import size in for `%s', imported from %s: 0x%02X",
@ -193,10 +197,11 @@ Import* GenImport (unsigned Name, unsigned char AddrSize)
* invalid. Be sure not to access it in this case.
*/
if (ObjHasFiles (I->Obj)) {
const LineInfo* LI = GetImportPos (I);
Error ("Invalid import size in for `%s', imported from %s(%lu): 0x%02X",
GetString (I->Name),
GetSourceFileName (I->Obj, I->Pos.Name),
I->Pos.Line,
GetSourceName (LI),
GetSourceLine (LI),
I->AddrSize);
} else {
Error ("Invalid import size in for `%s', imported from %s: 0x%02X",
@ -269,6 +274,15 @@ Import* InsertImport (Import* I)
const LineInfo* GetImportPos (const Import* I)
/* Return the basic line info of an import */
{
/* Source file position is always in slot zero */
return CollConstAt (&I->LineInfos, 0);
}
/*****************************************************************************/
/* Code */
/*****************************************************************************/
@ -283,16 +297,16 @@ static Export* NewExport (unsigned char Type, unsigned char AddrSize,
Export* E = xmalloc (sizeof (Export));
/* Initialize the fields */
E->Name = Name;
E->Next = 0;
E->Flags = 0;
E->Obj = Obj;
E->ImpCount = 0;
E->ImpList = 0;
E->Expr = 0;
InitFilePos (&E->Pos);
E->Type = Type;
E->AddrSize = AddrSize;
E->Name = Name;
E->Next = 0;
E->Flags = 0;
E->Obj = Obj;
E->ImpCount = 0;
E->ImpList = 0;
E->Expr = 0;
E->LineInfos = EmptyCollection;
E->Type = Type;
E->AddrSize = AddrSize;
memset (E->ConDes, 0, sizeof (E->ConDes));
/* Return the new entry */
@ -310,6 +324,9 @@ void FreeExport (Export* E)
/* Safety */
PRECONDITION ((E->Flags & EXP_INLIST) == 0);
/* Free the line infos */
DoneCollection (&E->LineInfos);
/* Free the export expression */
FreeExpr (E->Expr);
@ -319,6 +336,63 @@ void FreeExport (Export* E)
Export* ReadExport (FILE* F, ObjData* O)
/* Read an export from a file */
{
unsigned ConDesCount;
Export* E;
/* Read the type */
unsigned char Type = ReadVar (F);
/* Read the address size */
unsigned char AddrSize = Read8 (F);
/* Create a new export without a name */
E = NewExport (Type, AddrSize, INVALID_STRING_ID, O);
/* Read the constructor/destructor decls if we have any */
ConDesCount = SYM_GET_CONDES_COUNT (Type);
if (ConDesCount > 0) {
unsigned char ConDes[CD_TYPE_COUNT];
unsigned I;
/* Read the data into temp storage */
ReadData (F, ConDes, ConDesCount);
/* Re-order the data. In the file, each decl is encoded into a byte
* which contains the type and the priority. In memory, we will use
* an array of types which contain the priority. This array was
* cleared by the constructor (NewExport), so we must only set the
* fields that contain values.
*/
for (I = 0; I < ConDesCount; ++I) {
unsigned ConDesType = CD_GET_TYPE (ConDes[I]);
unsigned ConDesPrio = CD_GET_PRIO (ConDes[I]);
E->ConDes[ConDesType] = ConDesPrio;
}
}
/* Read the name */
E->Name = MakeGlobalStringId (O, ReadVar (F));
/* Read the value */
if (SYM_IS_EXPR (Type)) {
E->Expr = ReadExpr (F, O);
} else {
E->Expr = LiteralExpr (Read32 (F), O);
}
/* Last is the file position where the definition was done */
ReadLineInfoList (F, O, &E->LineInfos);
/* Return the new export */
return E;
}
void InsertExport (Export* E)
/* Insert an exported identifier and check if it's already in the list */
{
@ -393,59 +467,11 @@ void InsertExport (Export* E)
Export* ReadExport (FILE* F, ObjData* O)
/* Read an export from a file */
const LineInfo* GetExportPos (const Export* E)
/* Return the basic line info of an export */
{
unsigned ConDesCount;
Export* E;
/* Read the type */
unsigned char Type = ReadVar (F);
/* Read the address size */
unsigned char AddrSize = Read8 (F);
/* Create a new export without a name */
E = NewExport (Type, AddrSize, INVALID_STRING_ID, O);
/* Read the constructor/destructor decls if we have any */
ConDesCount = SYM_GET_CONDES_COUNT (Type);
if (ConDesCount > 0) {
unsigned char ConDes[CD_TYPE_COUNT];
unsigned I;
/* Read the data into temp storage */
ReadData (F, ConDes, ConDesCount);
/* Re-order the data. In the file, each decl is encoded into a byte
* which contains the type and the priority. In memory, we will use
* an array of types which contain the priority. This array was
* cleared by the constructor (NewExport), so we must only set the
* fields that contain values.
*/
for (I = 0; I < ConDesCount; ++I) {
unsigned ConDesType = CD_GET_TYPE (ConDes[I]);
unsigned ConDesPrio = CD_GET_PRIO (ConDes[I]);
E->ConDes[ConDesType] = ConDesPrio;
}
}
/* Read the name */
E->Name = MakeGlobalStringId (O, ReadVar (F));
/* Read the value */
if (SYM_IS_EXPR (Type)) {
E->Expr = ReadExpr (F, O);
} else {
E->Expr = LiteralExpr (Read32 (F), O);
}
/* Last is the file position where the definition was done */
ReadFilePos (F, &E->Pos);
/* Return the new export */
return E;
/* Source file position is always in slot zero */
return CollConstAt (&E->LineInfos, 0);
}
@ -617,6 +643,8 @@ static void CheckSymType (const Export* E)
StrBuf ImportLoc = STATIC_STRBUF_INITIALIZER;
const char* ExpAddrSize = AddrSizeToStr (E->AddrSize);
const char* ImpAddrSize = AddrSizeToStr (I->AddrSize);
const LineInfo* ExportLI = GetExportPos (E);
const LineInfo* ImportLI = GetImportPos (I);
/* Generate strings that describe the location of the im- and
* exports. This depends on the place from where they come:
@ -626,23 +654,23 @@ static void CheckSymType (const Export* E)
/* The export comes from an object file */
SB_Printf (&ExportLoc, "%s, %s(%lu)",
GetString (E->Obj->Name),
GetSourceFileName (E->Obj, E->Pos.Name),
E->Pos.Line);
GetSourceName (ExportLI),
GetSourceLine (ExportLI));
} else {
SB_Printf (&ExportLoc, "%s(%lu)",
GetSourceFileName (E->Obj, E->Pos.Name),
E->Pos.Line);
GetSourceName (ExportLI),
GetSourceLine (ExportLI));
}
if (I->Obj) {
/* The import comes from an object file */
SB_Printf (&ImportLoc, "%s, %s(%lu)",
GetString (I->Obj->Name),
GetSourceFileName (I->Obj, I->Pos.Name),
I->Pos.Line);
GetSourceName (ImportLI),
GetSourceLine (ImportLI));
} else {
SB_Printf (&ImportLoc, "%s(%lu)",
GetSourceFileName (I->Obj, I->Pos.Name),
I->Pos.Line);
GetSourceName (ImportLI),
GetSourceLine (ImportLI));
}
/* Output the diagnostic */
@ -699,8 +727,11 @@ static void PrintUnresolved (ExpCheckFunc F, void* Data)
"Unresolved external `%s' referenced in:\n",
GetString (E->Name));
while (Imp) {
const char* Name = GetSourceFileName (Imp->Obj, Imp->Pos.Name);
fprintf (stderr, " %s(%lu)\n", Name, Imp->Pos.Line);
const LineInfo* LI = GetImportPos (Imp);
fprintf (stderr,
" %s(%lu)\n",
GetSourceName (LI),
GetSourceLine (LI));
Imp = Imp->Next;
}
}
@ -850,11 +881,12 @@ void PrintImportMap (FILE* F)
while (Imp) {
/* Print the import */
const LineInfo* LI = GetImportPos (Imp);
fprintf (F,
" %-25s %s(%lu)\n",
GetObjFileName (Imp->Obj),
GetSourceFileName (Imp->Obj, Imp->Pos.Name),
Imp->Pos.Line);
GetSourceName (LI),
GetSourceLine (LI));
/* Next import */
Imp = Imp->Next;
@ -907,10 +939,11 @@ int ExportHasMark (Export* E)
void CircularRefError (const Export* E)
/* Print an error about a circular reference using to define the given export */
{
const LineInfo* LI = GetExportPos (E);
Error ("Circular reference for symbol `%s', %s(%lu)",
GetString (E->Name),
GetSourceFileName (E->Obj, E->Pos.Name),
E->Pos.Line);
GetSourceName (LI),
GetSourceLine (LI));
}

View File

@ -6,7 +6,7 @@
/* */
/* */
/* */
/* (C) 1998-2010, Ullrich von Bassewitz */
/* (C) 1998-2011, Ullrich von Bassewitz */
/* Roemerstrasse 52 */
/* D-70794 Filderstadt */
/* EMail: uz@cc65.org */
@ -42,11 +42,12 @@
/* common */
#include "cddefs.h"
#include "coll.h"
#include "exprdefs.h"
#include "filepos.h"
/* ld65 */
#include "config.h"
#include "lineinfo.h"
#include "memarea.h"
#include "objdata.h"
@ -63,7 +64,7 @@ typedef struct Import Import;
struct Import {
Import* Next; /* Single linked list */
ObjData* Obj; /* Object file that imports the name */
FilePos Pos; /* File position of reference */
Collection LineInfos; /* Line info of reference */
struct Export* Exp; /* Matching export for this import */
unsigned Name; /* Name if not in table */
unsigned char Flags; /* Generic flags */
@ -82,7 +83,7 @@ struct Export {
unsigned ImpCount; /* How many imports for this symbol? */
Import* ImpList; /* List of imports for this symbol */
ExprNode* Expr; /* Expression (0 if not def'd) */
FilePos Pos; /* File position of definition */
Collection LineInfos; /* Line info of definition */
unsigned char Type; /* Type of export */
unsigned char AddrSize; /* Address size of export */
unsigned char ConDes[CD_TYPE_COUNT]; /* Constructor/destructor decls */
@ -121,6 +122,9 @@ Import* GenImport (unsigned Name, unsigned char AddrSize);
Import* InsertImport (Import* I);
/* Insert an import into the table, return I */
const LineInfo* GetImportPos (const Import* I);
/* Return the basic line info of an import */
void FreeExport (Export* E);
/* Free an export. NOTE: This won't remove the export from the exports table,
* so it may only be called for unused exports (exports from modules that
@ -133,6 +137,9 @@ Export* ReadExport (FILE* F, ObjData* Obj);
void InsertExport (Export* E);
/* Insert an exported identifier and check if it's already in the list */
const LineInfo* GetExportPos (const Export* E);
/* Return the basic line info of an export */
Export* CreateConstExport (unsigned Name, long Value);
/* Create an export for a literal date */

View File

@ -6,7 +6,7 @@
/* */
/* */
/* */
/* (C) 1998-2010, Ullrich von Bassewitz */
/* (C) 1998-2011, Ullrich von Bassewitz */
/* Roemerstrasse 52 */
/* D-70794 Filderstadt */
/* EMail: uz@cc65.org */
@ -40,7 +40,6 @@
/* ld65 */
#include "error.h"
#include "fragment.h"
#include "lineinfo.h"
#include "objdata.h"
#include "segments.h"
@ -115,27 +114,3 @@ void FragResolveLineInfos (Fragment* F)
const char* GetFragmentSourceName (const Fragment* F)
/* Return the name of the source file for this fragment */
{
/* Each fragment has the basic info in line info #0 */
const LineInfo* LI = CollConstAt (&F->LineInfos, 0);
/* Return the source file name */
return GetSourceFileName (F->Obj, LI->Pos.Name);
}
unsigned long GetFragmentSourceLine (const Fragment* F)
/* Return the source file line for this fragment */
{
/* Each fragment has the basic info in line info #0 */
const LineInfo* LI = CollConstAt (&F->LineInfos, 0);
/* Return the source file line */
return LI->Pos.Line;
}

View File

@ -6,7 +6,7 @@
/* */
/* */
/* */
/* (C) 1998-2010, Ullrich von Bassewitz */
/* (C) 1998-2011, Ullrich von Bassewitz */
/* Roemerstrasse 52 */
/* D-70794 Filderstadt */
/* EMail: uz@cc65.org */
@ -42,15 +42,16 @@
#include "coll.h"
#include "filepos.h"
/* Ld65 */
#include "lineinfo.h"
/*****************************************************************************/
/* Forwards */
/* Forwards */
/*****************************************************************************/
struct LineInfo;
struct ObjData;
struct Section;
@ -89,11 +90,25 @@ Fragment* NewFragment (unsigned char Type, unsigned Size, struct Section* S);
void FragResolveLineInfos (Fragment* F);
/* Resolve the back pointers for the line infos */
const char* GetFragmentSourceName (const Fragment* F);
#if defined(HAVE_INLINE)
INLINE const char* GetFragmentSourceName (const Fragment* F)
/* Return the name of the source file for this fragment */
{
return GetSourceNameFromList (&F->LineInfos);
}
#else
# define GetFragmentSourceName(LI) GetSourceNameFromList (&(F)->LineInfos)
#endif
unsigned long GetFragmentSourceLine (const Fragment* F);
#if defined(HAVE_INLINE)
INLINE unsigned long GetFragmentSourceLine (const Fragment* F)
/* Return the source file line for this fragment */
{
return GetSourceLineFromList (&F->LineInfos);
}
#else
# define GetFragmentSourceLine(LI) GetSourceLineFromList (&(F)->LineInfos)
#endif

View File

@ -1,6 +1,6 @@
/*****************************************************************************/
/* */
/* lineinfo.h */
/* lineinfo.h */
/* */
/* Source file line info structure */
/* */
@ -38,11 +38,13 @@
#include "xmalloc.h"
/* ld65 */
#include "error.h"
#include "fileinfo.h"
#include "fileio.h"
#include "fragment.h"
#include "lineinfo.h"
#include "objdata.h"
#include "segments.h"
#include "lineinfo.h"
@ -69,20 +71,19 @@ static CodeRange* NewCodeRange (Segment* Seg, unsigned long Offs, unsigned long
static LineInfo* NewLineInfo (ObjData* O, const FilePos* Pos)
/* Create and return a new LineInfo struct */
static LineInfo* NewLineInfo (void)
/* Create and return a new LineInfo struct with mostly empty fields */
{
/* Allocate memory */
LineInfo* LI = xmalloc (sizeof (LineInfo));
/* Make sure the name index is valid */
CHECK (Pos->Name < CollCount (&O->Files));
/* Initialize the fields */
LI->File = CollAt (&O->Files, Pos->Name);
LI->Pos = *Pos;
InitCollection (&LI->Fragments);
InitCollection (&LI->CodeRanges);
LI->Pos.Name = INVALID_STRING_ID;
LI->Pos.Line = 0;
LI->Pos.Col = 0;
LI->File = 0;
LI->Fragments = EmptyCollection;
LI->CodeRanges = EmptyCollection;
/* Return the new struct */
return LI;
@ -90,15 +91,35 @@ static LineInfo* NewLineInfo (ObjData* O, const FilePos* Pos)
LineInfo* GenLineInfo (const FilePos* Pos)
/* Generate a new (internally used) line info with the given information */
{
/* Create a new LineInfo struct */
LineInfo* LI = NewLineInfo ();
/* Initialize the fields in the new LineInfo */
LI->Pos = *Pos;
/* Return the struct read */
return LI;
}
LineInfo* ReadLineInfo (FILE* F, ObjData* O)
/* Read a line info from a file and return it */
{
/* Read the file position */
FilePos Pos;
ReadFilePos (F, &Pos);
/* Create a new LineInfo struct */
LineInfo* LI = NewLineInfo ();
/* Allocate a new LineInfo struct, initialize and return it */
return NewLineInfo (O, &Pos);
/* Read/fill the fields in the new LineInfo */
LI->Pos.Line = ReadVar (F);
LI->Pos.Col = ReadVar (F);
LI->File = CollAt (&O->Files, ReadVar (F));
LI->Pos.Name = LI->File->Name;
/* Return the struct read */
return LI;
}
@ -221,3 +242,4 @@ void RelocLineInfo (Segment* S)

View File

@ -44,6 +44,9 @@
#include "coll.h"
#include "filepos.h"
/* ld65 */
#include "spool.h"
/*****************************************************************************/
@ -72,10 +75,14 @@ struct CodeRange {
/* Structure holding line information. The Pos.Name field is always the
* global string id of the file name. If the line info was read from the
* object file, the File pointer is valid, otherwise it is NULL.
*/
typedef struct LineInfo LineInfo;
struct LineInfo {
struct FileInfo* File; /* File struct for this line */
FilePos Pos; /* File position */
struct FileInfo* File; /* File struct for this line if any */
FilePos Pos; /* Position in file */
Collection Fragments; /* Fragments for this line */
Collection CodeRanges; /* Code ranges for this line */
};
@ -88,6 +95,9 @@ struct LineInfo {
LineInfo* GenLineInfo (const FilePos* Pos);
/* Generate a new (internally used) line info with the given information */
LineInfo* ReadLineInfo (FILE* F, struct ObjData* O);
/* Read a line info from a file and return it */
@ -99,6 +109,70 @@ void ReadLineInfoList (FILE* F, struct ObjData* O, Collection* LineInfos);
void RelocLineInfo (struct Segment* S);
/* Relocate the line info for a segment. */
#if defined(HAVE_INLINE)
INLINE const FilePos* GetSourcePos (const LineInfo* LI)
/* Return the source file position from the given line info */
{
return &LI->Pos;
}
#else
# define GetSourcePos(LI) (&(LI)->Pos)
#endif
#if defined(HAVE_INLINE)
INLINE const char* GetSourceName (const LineInfo* LI)
/* Return the name of a source file from the given line info */
{
return GetString (LI->Pos.Name);
}
#else
# define GetSourceName(LI) (GetString ((LI)->Pos.Name))
#endif
#if defined(HAVE_INLINE)
INLINE unsigned long GetSourceLine (const LineInfo* LI)
/* Return the source file line from the given line info */
{
return LI->Pos.Line;
}
#else
# define GetSourceLine(LI) ((LI)->Pos.Line)
#endif
#if defined(HAVE_INLINE)
INLINE unsigned GetSourceCol (const LineInfo* LI)
/* Return the source file column from the given line info */
{
return LI->Pos.Col;
}
#else
# define GetSourceCol(LI) ((LI)->Pos.Col)
#endif
#if defined(HAVE_INLINE)
INLINE const char* GetSourceNameFromList (const Collection* LineInfos)
/* Return the name of a source file from a list of line infos */
{
/* The relevant entry is in slot zero */
return GetSourceName (CollConstAt (LineInfos, 0));
}
#else
# define GetSourceNameFromList(LineInfos) \
GetSourceName ((const LineInfo*) CollConstAt ((LineInfos), 0))
#endif
#if defined(HAVE_INLINE)
INLINE unsigned long GetSourceLineFromList (const Collection* LineInfos)
/* Return the source file line from a list of line infos */
{
/* The relevant entry is in slot zero */
return GetSourceLine (CollConstAt (LineInfos, 0));
}
#else
# define GetSourceLineFromList(LineInfos) \
GetSourceLine ((const LineInfo*) CollConstAt ((LineInfos), 0))
#endif
/* End of lineinfo.h */

View File

@ -6,7 +6,7 @@
/* */
/* */
/* */
/* (C) 2010, Ullrich von Bassewitz */
/* (C) 2010-2011, Ullrich von Bassewitz */
/* Roemerstrasse 52 */
/* D-70794 Filderstadt */
/* EMail: uz@cc65.org */
@ -54,7 +54,7 @@ MemoryArea* NewMemoryArea (const FilePos* Pos, unsigned Name)
MemoryArea* M = xmalloc (sizeof (MemoryArea));
/* Initialize the fields ... */
M->Pos = *Pos;
M->LI = GenLineInfo (Pos);
M->Name = Name;
M->Attr = 0;
M->Flags = 0;
@ -65,7 +65,7 @@ MemoryArea* NewMemoryArea (const FilePos* Pos, unsigned Name)
M->FillLevel = 0;
M->FillVal = 0;
M->Relocatable = 0;
InitCollection (&M->SegList);
M->SegList = EmptyCollection;
M->F = 0;
/* ...and return it */

View File

@ -6,7 +6,7 @@
/* */
/* */
/* */
/* (C) 2010, Ullrich von Bassewitz */
/* (C) 2010-2011, Ullrich von Bassewitz */
/* Roemerstrasse 52 */
/* D-70794 Filderstadt */
/* EMail: uz@cc65.org */
@ -40,7 +40,9 @@
/* common */
#include "coll.h"
#include "filepos.h"
/* ld65 */
#include "lineinfo.h"
@ -57,7 +59,7 @@ struct File;
/* Memory area entry */
typedef struct MemoryArea MemoryArea;
struct MemoryArea {
FilePos Pos; /* Where was the area was defined? */
LineInfo* LI; /* Where was the area was defined? */
unsigned Name; /* Name index of the memory area */
unsigned Attr; /* Which values are valid? */
unsigned Flags; /* Set of bitmapped flags */

View File

@ -181,42 +181,3 @@ const char* GetObjFileName (const ObjData* O)
const char* GetSourceFileName (const ObjData* O, unsigned Index)
/* Get the name of the source file with the given index. If O is NULL, return
* "[linker generated]" as the file name.
*/
{
/* Check if we have an object file */
if (O == 0) {
/* No object file */
if (Index == INVALID_STRING_ID) {
return "[linker generated]";
} else {
return GetString (Index);
}
} else {
/* Check the parameter */
if (Index >= CollCount (&O->Files)) {
/* Error() will terminate the program */
Warning ("Invalid file index (%u) in module `%s' (input file corrupt?)",
Index, GetObjFileName (O));
return "[invalid]"; /* ### */
} else {
/* Get a pointer to the file info struct */
const FileInfo* FI = CollConstAt (&O->Files, Index);
/* Return the name */
return GetString (FI->Name);
}
}
}

View File

@ -129,11 +129,6 @@ INLINE int ObjHasFiles (const ObjData* O)
# define ObjHasFiles(O) ((O) != 0 && CollCount (&(O)->Files) != 0)
#endif
const char* GetSourceFileName (const ObjData* O, unsigned Index);
/* Get the name of the source file with the given index. If O is NULL, return
* "[linker generated]" as the file name.
*/
/* End of objdata.h */

View File

@ -553,20 +553,6 @@ void CfgSetName (const char* Name)
const char* CfgGetName (void)
/* Get the name of the config file */
{
if (CfgName) {
return CfgName;
} else if (CfgBuf) {
return "[builtin config]";
} else {
return "";
}
}
void CfgSetBuf (const char* Buf)
/* Set a memory buffer for the config */
{

View File

@ -165,10 +165,10 @@ extern StrBuf CfgSVal;
extern unsigned long CfgIVal;
/* Error location. PLEASE NOTE: I'm abusing the FilePos structure to some
* degree. It is used mostly to hold a file position, where the Name member
* degree. It is used mostly to hold a file position, where the Name member
* is an index into the source file table of an object file. As used in config
* file processing, the Name member is a string pool index instead. This is
* distinguished by the object file pointer being NULL or not in the structs
* distinguished by the object file pointer being NULL or not in the structs
* where this is relevant.
*/
extern FilePos CfgErrorPos;
@ -226,9 +226,6 @@ void CfgBoolToken (void);
void CfgSetName (const char* Name);
/* Set a name for a config file */
const char* CfgGetName (void);
/* Get the name of the config file */
void CfgSetBuf (const char* Buf);
/* Set a memory buffer for the config */