Report a bug
If you spot a problem with this page, click here to create a Bugzilla issue.
Improve this page
Quickly fork, edit online, and submit a pull request for this page. Requires a signed-in GitHub account. This works well for small changes. If you'd like to make larger changes you may want to consider using a local clone.

dmd.location

Encapsulates file/line/column locations.
Authors:

Source location.d

Jump to: digitalmars · gnu · sarif

enum MessageStyle: ubyte;
How code locations are formatted for diagnostic reporting
digitalmars
filename.d(line): message
gnu
sarif
struct Loc;
A source code location
Used for error messages, __FILE__ and __LINE__ tokens, __traits(getLocation, XXX), debug info etc.
static immutable Loc initial;
use for default initialization of Loc's
static nothrow void set(bool showColumns, MessageStyle messageStyle);
Configure how display is done
Parameters:
bool showColumns when to display columns
MessageStyle messageStyle digitalmars or gnu style messages
static nothrow Loc singleFilename(const char* filename);
Returns:
a Loc that simply holds a filename, with no line / column info
nothrow @nogc @safe uint charnum() const;
utf8 code unit index relative to start of line, starting from 1
nothrow @nogc @trusted uint linnum() const;
line number, starting from 1
nothrow void nextLine();
Advance this location to the first column of the next line
nothrow @nogc const(char)* filename() const;
Returns:
filename for this location, null if none
nothrow uint fileOffset() const;
Returns:
byte offset into source file
nothrow @nogc @safe SourceLoc toSourceLoc() const;
Returns:
this location as a SourceLoc
nothrow bool equals(Loc loc) const;
Checks for equivalence by comparing the filename contents (not the pointer) and character location.

Note

  • Uses case-insensitive comparison on Windows
  • Ignores charnum if Columns is false.

nothrow @nogc @trusted bool opEquals(ref const(Loc) loc) const;

nothrow @trusted size_t toHash() const;
opEquals() / toHash() for AA key usage
Compare filename contents (case-sensitively on Windows too), not the pointer - a static foreach loop repeatedly mixing in a mixin may lead to multiple equivalent filenames (foo.d-mixin-<line>), e.g., for test/runnable/test18880.d.
pure nothrow @safe bool isValid() const;
Returns:
true if Loc has been set to other than the default initialization
nothrow void writeSourceLoc(ref OutBuffer buf, SourceLoc loc, bool showColumns, MessageStyle messageStyle);
Format a source location for error messages
Parameters:
OutBuffer buf buffer to write string into
SourceLoc loc source location to write
bool showColumns include column number in message
MessageStyle messageStyle select error message format

Jump to: column · filename · fileOffset · line

struct SourceLoc;
Describes a location in the source code as a file + line number + column number
While Loc is a compact opaque location meant to be stored in the AST, this struct has simple modifiable fields and is used for printing.
const(char)[] filename;
name of source file
uint line;
line number (starts at 1)
uint column;
column number (starts at 1)
uint fileOffset;
byte index into file
nothrow BaseLoc* newBaseLoc(const(char)* filename, size_t size);
Create a new source location map for a file
Parameters:
const(char)* filename source file name
size_t size space to reserve for locations, equal to the file size in bytes
Returns:
new BaseLoc
struct BaseLoc;
Mapping from byte offset into source file to line/column numbers
Consider this 4-line 24 byte source file:
app.d
1 struct S
2 {
3     int y;
4 }
Loc(0) is reserved for null locations, so the first BaseLoc gets startIndex = 1 and reserves 25 possible positions. Loc(1) represents the very start of this source file, and every next byte gets the next Loc, up to Loc(25) which represents the location right past the very last } character (hence it's 1 more than the file size of 24, classic fence post problem!).
The next source file will get Loc(26) .. Loc(26 + fileSize + 1) etc.
Now say we know that int y has a Loc(20) and we want to know the line and column number.
First we find the corresponding BaseLoc in locFileTable. Since 20 < 26, the first BaseLoc contains this location. Since startIndex = 1, we subtract that to get a file offset 19.
To get the line number from the file offset, we binary search into the lines array, which contains file offsets where each line starts:
locFileTable[0].lines == [0, 9, 11, 22, 24]
We see 14 would be inserted right after 11 at lines[2], so it's line 3 (+1 for 1-indexing). Since line 3 starts at file offset 11, and 14 - 11 = 3, it's column 4 (again, accounting for 1-indexing)
#line and #file directives are handled with a separate array substitutions because they're rare, and we don't want to penalize memory usage in their absence.
const(char)[] filename;
Source file name
uint startIndex;
Subtract this from Loc.index to get file offset
int startLine;
Line number at index 0
uint[] lines;
For each line, the file offset at which it starts. At index 0 there's always a 0 entry.
BaseLoc[] substitutions;
Substitutions from #line / #file directives
nothrow @safe void newLine(uint offset);
Register that a new line starts at offset bytes from the start of the source file
nothrow @nogc @safe Loc getLoc(uint offset);
Construct a Loc entry for the start of the source file + offset bytes
nothrow @system void addSubstitution(uint offset, const(char)* filename, uint line);
Register a new file/line mapping from #file and #line directives
Parameters:
uint offset byte offset in the source file at which the substitution starts
const(char)* filename new filename from this point on (null = unchanged)
uint line line number from this point on
nothrow @nogc @safe SourceLoc substitute(SourceLoc loc);
Returns:
loc modified by substitutions from #file / #line directives