From 733e832b5d9719acb92a411a0a80ac0ad60d5093 Mon Sep 17 00:00:00 2001 From: uz Date: Wed, 26 Jan 2011 19:42:17 +0000 Subject: [PATCH] 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 --- src/ld65/asserts.c | 38 ++------ src/ld65/cfgexpr.c | 3 +- src/ld65/config.c | 63 +++++++------ src/ld65/config.h | 5 +- src/ld65/dbginfo.c | 4 +- src/ld65/dbgsyms.c | 24 ++--- src/ld65/dbgsyms.h | 12 +-- src/ld65/exports.c | 217 +++++++++++++++++++++++++------------------- src/ld65/exports.h | 15 ++- src/ld65/fragment.c | 27 +----- src/ld65/fragment.h | 25 ++++- src/ld65/lineinfo.c | 54 +++++++---- src/ld65/lineinfo.h | 78 +++++++++++++++- src/ld65/memarea.c | 6 +- src/ld65/memarea.h | 8 +- src/ld65/objdata.c | 39 -------- src/ld65/objdata.h | 5 - src/ld65/scanner.c | 14 --- src/ld65/scanner.h | 7 +- 19 files changed, 349 insertions(+), 295 deletions(-) diff --git a/src/ld65/asserts.c b/src/ld65/asserts.c index 67ecf28a4..d71190702 100644 --- a/src/ld65/asserts.c +++ b/src/ld65/asserts.c @@ -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) } } } - + diff --git a/src/ld65/cfgexpr.c b/src/ld65/cfgexpr.c index 668d0443b..3057e054c 100644 --- a/src/ld65/cfgexpr.c +++ b/src/ld65/cfgexpr.c @@ -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 */ diff --git a/src/ld65/config.c b/src/ld65/config.c index a67a3127e..f6e2ff0ed 100644 --- a/src/ld65/config.c +++ b/src/ld65/config.c @@ -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); } diff --git a/src/ld65/config.h b/src/ld65/config.h index 3a4cbc852..9394f86ca 100644 --- a/src/ld65/config.h +++ b/src/ld65/config.h @@ -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 */ diff --git a/src/ld65/dbginfo.c b/src/ld65/dbginfo.c index 98227790b..acd567172 100644 --- a/src/ld65/dbginfo.c +++ b/src/ld65/dbginfo.c @@ -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); } diff --git a/src/ld65/dbgsyms.c b/src/ld65/dbgsyms.c index 071ccdc64..850739a26 100644 --- a/src/ld65/dbgsyms.c +++ b/src/ld65/dbgsyms.c @@ -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; diff --git a/src/ld65/dbgsyms.h b/src/ld65/dbgsyms.h index 5ad169453..4736cce9b 100644 --- a/src/ld65/dbgsyms.h +++ b/src/ld65/dbgsyms.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 */ @@ -41,8 +41,8 @@ #include /* 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 */ diff --git a/src/ld65/exports.c b/src/ld65/exports.c index 3d76b73a3..c8722f19e 100644 --- a/src/ld65/exports.c +++ b/src/ld65/exports.c @@ -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)); } diff --git a/src/ld65/exports.h b/src/ld65/exports.h index 281b24805..83318bef3 100644 --- a/src/ld65/exports.h +++ b/src/ld65/exports.h @@ -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 */ diff --git a/src/ld65/fragment.c b/src/ld65/fragment.c index 55a9847d0..eabb9be58 100644 --- a/src/ld65/fragment.c +++ b/src/ld65/fragment.c @@ -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; -} - - - diff --git a/src/ld65/fragment.h b/src/ld65/fragment.h index 9146aa272..b3f406ef6 100644 --- a/src/ld65/fragment.h +++ b/src/ld65/fragment.h @@ -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 diff --git a/src/ld65/lineinfo.c b/src/ld65/lineinfo.c index be087096b..5c4a22cdd 100644 --- a/src/ld65/lineinfo.c +++ b/src/ld65/lineinfo.c @@ -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) + diff --git a/src/ld65/lineinfo.h b/src/ld65/lineinfo.h index fb7da7193..dd6258f6f 100644 --- a/src/ld65/lineinfo.h +++ b/src/ld65/lineinfo.h @@ -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 */ diff --git a/src/ld65/memarea.c b/src/ld65/memarea.c index fb54e3e05..c95fca61b 100644 --- a/src/ld65/memarea.c +++ b/src/ld65/memarea.c @@ -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 */ diff --git a/src/ld65/memarea.h b/src/ld65/memarea.h index 433e995e5..d67b9926b 100644 --- a/src/ld65/memarea.h +++ b/src/ld65/memarea.h @@ -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 */ diff --git a/src/ld65/objdata.c b/src/ld65/objdata.c index 6f7e28bc1..9d71a3ab9 100644 --- a/src/ld65/objdata.c +++ b/src/ld65/objdata.c @@ -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); - - } - } -} - - - - diff --git a/src/ld65/objdata.h b/src/ld65/objdata.h index 9efbf85de..2ea3d418f 100644 --- a/src/ld65/objdata.h +++ b/src/ld65/objdata.h @@ -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 */ diff --git a/src/ld65/scanner.c b/src/ld65/scanner.c index 5a7a6e46e..9e8e101a9 100644 --- a/src/ld65/scanner.c +++ b/src/ld65/scanner.c @@ -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 */ { diff --git a/src/ld65/scanner.h b/src/ld65/scanner.h index 8b90aab80..1cb71181c 100644 --- a/src/ld65/scanner.h +++ b/src/ld65/scanner.h @@ -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 */