/* ld65 */
#include "asserts.h"
#include "error.h"
-#include "expr.h"
+#include "expr.h"
#include "fileio.h"
#include "lineinfo.h"
#include "objdata.h"
-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 */
{
/* Walk over all assertions */
for (I = 0; I < CollCount (&Assertions); ++I) {
+ const LineInfo* LI;
const char* Module;
unsigned long Line;
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)) {
}
}
}
-
+
#include "error.h"
#include "exports.h"
#include "expr.h"
+#include "lineinfo.h"
#include "scanner.h"
#include "spool.h"
} 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 */
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 */
/* Initialize the fields */
Sym->Type = Type;
- Sym->Pos = CfgErrorPos;
+ Sym->LI = GenLineInfo (&CfgErrorPos);
Sym->Name = Name;
Sym->Value = 0;
Sym->AddrSize = ADDR_SIZE_INVALID;
/* Initialize the fields */
S->Name = Name;
- S->Pos = CfgErrorPos;
+ S->LI = GenLineInfo (&CfgErrorPos);
S->Seg = 0;
S->Attr = 0;
S->Flags = 0;
* 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;
}
* 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 */
AttrCheck (AttrFlags, atType, "TYPE");
/* Create the export */
Exp = CreateExprExport (Name, Value, AddrSize);
- Exp->Pos = CfgErrorPos;
+ CollAppend (&Exp->LineInfos, GenLineInfo (&CfgErrorPos));
break;
case CfgSymImport:
/* Generate the import */
Imp = InsertImport (GenImport (Name, AddrSize));
/* Remember the file position */
- Imp->Pos = CfgErrorPos;
+ CollAppend (&Imp->LineInfos, GenLineInfo (&CfgErrorPos));
break;
case CfgSymWeak:
* 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
/* 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)
);
*/
if (O65GetExport (O65FmtDesc, Sym->Name) != 0) {
CfgError (
- &Sym->Pos,
+ GetSourcePos (Sym->LI),
"Duplicate exported o65 symbol: `%s'",
GetString (Sym->Name)
);
/* 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)
);
*/
if (O65GetImport (O65FmtDesc, Sym->Name) != 0) {
CfgError (
- &Sym->Pos,
+ GetSourcePos (Sym->LI),
"Duplicate imported o65 symbol: `%s'",
GetString (Sym->Name)
);
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;
/* 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);
/* 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);
* 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));
}
/* 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));
}
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));
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
/* 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);
}
#include "filepos.h"
/* ld65 */
+#include "lineinfo.h"
#include "segments.h"
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 */
void CfgWriteTarget (void);
/* Write the target file(s) */
-
+
/* End of config.h */
/* */
/* */
/* */
-/* (C) 2001-2010, Ullrich von Bassewitz */
+/* (C) 2001-2011, Ullrich von Bassewitz */
/* Roemerstrasse 52 */
/* D-70794 Filderstadt */
/* EMail: uz@cc65.org */
/* 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);
}
/* */
/* */
/* */
-/* (C) 1998-2010, Ullrich von Bassewitz */
+/* (C) 1998-2011, Ullrich von Bassewitz */
/* Roemerstrasse 52 */
/* D-70794 Filderstadt */
/* EMail: uz@cc65.org */
#include "expr.h"
#include "fileio.h"
#include "global.h"
+#include "lineinfo.h"
#include "objdata.h"
#include "spool.h"
/* 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;
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;
/* */
/* */
/* */
-/* (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 */
#include <stdio.h>
/* common */
+#include "coll.h"
#include "exprdefs.h"
-#include "filepos.h"
/* ld65 */
#include "objdata.h"
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 */
/* */
/* */
/* */
-/* (C) 1998-2010, Ullrich von Bassewitz */
+/* (C) 1998-2011, Ullrich von Bassewitz */
/* Roemerstrasse 52 */
/* D-70794 Filderstadt */
/* EMail: uz@cc65.org */
/* common */
#include "addrsize.h"
#include "check.h"
-#include "coll.h"
#include "hashstr.h"
#include "symdefs.h"
#include "xmalloc.h"
#include "expr.h"
#include "fileio.h"
#include "global.h"
+#include "lineinfo.h"
#include "memarea.h"
#include "objdata.h"
#include "spool.h"
/* 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;
/* Safety */
PRECONDITION ((I->Flags & IMP_INLIST) == 0);
+ /* Free the line info collection */
+ DoneCollection (&I->LineInfos);
+
/* Free the struct */
xfree (I);
}
/* 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) {
* 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",
* 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",
+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 */
/*****************************************************************************/
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 */
/* Safety */
PRECONDITION ((E->Flags & EXP_INLIST) == 0);
+ /* Free the line infos */
+ DoneCollection (&E->LineInfos);
+
/* Free the export expression */
FreeExpr (E->Expr);
+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 */
{
-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);
}
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:
/* 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 */
"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;
}
}
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;
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));
}
/* */
/* */
/* */
-/* (C) 1998-2010, Ullrich von Bassewitz */
+/* (C) 1998-2011, Ullrich von Bassewitz */
/* Roemerstrasse 52 */
/* D-70794 Filderstadt */
/* EMail: uz@cc65.org */
/* 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"
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 */
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 */
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
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 */
/* */
/* */
/* */
-/* (C) 1998-2010, Ullrich von Bassewitz */
+/* (C) 1998-2011, Ullrich von Bassewitz */
/* Roemerstrasse 52 */
/* D-70794 Filderstadt */
/* EMail: uz@cc65.org */
/* ld65 */
#include "error.h"
#include "fragment.h"
-#include "lineinfo.h"
#include "objdata.h"
#include "segments.h"
-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;
-}
-
-
-
/* */
/* */
/* */
-/* (C) 1998-2010, Ullrich von Bassewitz */
+/* (C) 1998-2011, Ullrich von Bassewitz */
/* Roemerstrasse 52 */
/* D-70794 Filderstadt */
/* EMail: uz@cc65.org */
#include "coll.h"
#include "filepos.h"
+/* Ld65 */
+#include "lineinfo.h"
/*****************************************************************************/
-/* Forwards */
+/* Forwards */
/*****************************************************************************/
-struct LineInfo;
struct ObjData;
struct Section;
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
/*****************************************************************************/
/* */
-/* lineinfo.h */
+/* lineinfo.h */
/* */
/* Source file line info structure */
/* */
#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"
-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;
+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 ();
+
+ /* 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;
- /* Allocate a new LineInfo struct, initialize and return it */
- return NewLineInfo (O, &Pos);
+ /* Return the struct read */
+ return LI;
}
+
#include "coll.h"
#include "filepos.h"
+/* ld65 */
+#include "spool.h"
+
/*****************************************************************************/
+/* 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 */
};
+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 */
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 */
/* */
/* */
/* */
-/* (C) 2010, Ullrich von Bassewitz */
+/* (C) 2010-2011, Ullrich von Bassewitz */
/* Roemerstrasse 52 */
/* D-70794 Filderstadt */
/* EMail: uz@cc65.org */
MemoryArea* M = xmalloc (sizeof (MemoryArea));
/* Initialize the fields ... */
- M->Pos = *Pos;
+ M->LI = GenLineInfo (Pos);
M->Name = Name;
M->Attr = 0;
M->Flags = 0;
M->FillLevel = 0;
M->FillVal = 0;
M->Relocatable = 0;
- InitCollection (&M->SegList);
+ M->SegList = EmptyCollection;
M->F = 0;
/* ...and return it */
/* */
/* */
/* */
-/* (C) 2010, Ullrich von Bassewitz */
+/* (C) 2010-2011, Ullrich von Bassewitz */
/* Roemerstrasse 52 */
/* D-70794 Filderstadt */
/* EMail: uz@cc65.org */
/* common */
#include "coll.h"
-#include "filepos.h"
+
+/* ld65 */
+#include "lineinfo.h"
/* 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 */
-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);
-
- }
- }
-}
-
-
-
-
# 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 */
-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 */
{
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;
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 */