@@ -72,21 +72,60 @@ package:
7272
7373struct LineDirectives {
7474 struct LineEntry {
75- Position position;
75+ uint offset;
76+ uint sline;
7677 Name filename;
7778 uint line;
7879 }
7980
80- LineEntry[] lineDirectives;
81+ LineEntry[] lineEntries;
82+ uint lastLineEntry;
8183
82- this (Position p, Name filename, uint line ) {
83- lineDirectives = [LineEntry(p, filename, line )];
84+ this (Name filename) {
85+ lineEntries = [LineEntry(0 , 0 , filename, 1 )];
8486 }
8587
86- void registerLineDirective (Position p, Name filename, uint line) {
87- if (lineDirectives[$ - 1 ].position < p) {
88- lineDirectives ~= LineEntry(p, filename, line);
88+ ref
89+ LineDirectives registerLineDirective (uint offset, uint sline, Name filename,
90+ uint line) in (lineEntries.length > 0 ) {
91+ auto previous = lineEntries[$ - 1 ];
92+ assert (previous.offset < offset,
93+ " Line directives must be register in order!" );
94+
95+ /**
96+ * FIXME: We need to diferentiate in between the case where no
97+ * filename is supplied and the case where it is explicitely
98+ * set as an empty string.
99+ */
100+ if (filename == BuiltinName! " " ) {
101+ filename = previous.filename;
102+ }
103+
104+ lineEntries ~= LineEntry(offset, sline, filename, line);
105+ return this ;
106+ }
107+
108+ auto findNearestLineEntry (uint offset) {
109+ if (! isOffsetInEntry(offset, lastLineEntry)) {
110+ import source.util.lookup;
111+ lastLineEntry =
112+ lookup! (e => e.offset, 8 )(lineEntries, offset, lastLineEntry);
89113 }
114+
115+ return lineEntries[lastLineEntry];
116+ }
117+
118+ bool isOffsetInEntry (uint offset, uint entry) {
119+ auto entryOffset = lineEntries[entry].offset;
120+ if (offset < entryOffset) {
121+ return false ;
122+ }
123+
124+ if (offset == entryOffset || entry + 1 == lineEntries.length) {
125+ return true ;
126+ }
127+
128+ return offset < lineEntries[entry + 1 ].offset;
90129 }
91130}
92131
@@ -106,7 +145,7 @@ public:
106145 Location location,
107146 Name filename,
108147 Name directory,
109- string content
148+ string content,
110149 ) out (result; result.isFile()) {
111150 return files
112151 .registerFileZeroTerminated(location, filename, directory, content);
@@ -137,10 +176,7 @@ public:
137176 return e.getLineNumber(o);
138177 }
139178
140- DebugLocation getDebugLocation (
141- Position p,
142- bool useLineDirective = EnableLineDirectiveByDefault
143- ) {
179+ DebugLocation getDebugLocation (Position p, bool useLineDirective = true ) {
144180 // Find an actual file.
145181 while (p.isMixin()) {
146182 p = getImportLocation(getFileID(p)).start;
@@ -150,26 +186,35 @@ public:
150186 auto e = &getSourceEntry(id);
151187 auto o = Location(e.base, p).length;
152188
153- auto filename = e.filename;
154189 auto line = e.getLineNumber(o);
155- auto column = o - e.getLineOffset(line);
190+ auto column = o - e.getLineOffset(line) + 1 ;
156191
157- if (useLineDirective && e.hasLineDirectives) {
158- assert ( 0 , " Line directive not supported! " );
192+ if (! useLineDirective || ! e.hasLineDirectives) {
193+ return DebugLocation (e.filename, line + 1 , column );
159194 }
160195
161- return DebugLocation (filename, line + 1 , column + 1 );
196+ auto lds = lineDirectives[id];
197+ auto lde = lds.findNearestLineEntry(o);
198+
199+ line += lde.line;
200+ line -= lde.sline;
201+
202+ return DebugLocation (lde.filename, line, column);
162203 }
163204
164205 void registerLineDirective (Position p, Name filename, uint line) {
165206 auto id = getFileID(p);
207+ auto e = &getSourceEntry(id);
208+ auto o = Location(e.base, p).length;
209+ auto sline = e.getLineNumber(o);
166210
167- getSourceEntry(id) .hasLineDirectives = true ;
211+ e .hasLineDirectives = true ;
168212 lineDirectives.update(
169213 id,
170- () => LineDirectives(p, filename, line),
214+ () => LineDirectives(e.filename)
215+ .registerLineDirective(o, sline, filename, line),
171216 (ref LineDirectives ds) =>
172- ds.registerLineDirective(p , filename, line)
217+ ds.registerLineDirective(o, sline , filename, line)
173218 );
174219 }
175220
@@ -364,12 +409,12 @@ public:
364409 }
365410
366411 @property
367- auto filename () const in (base.isFile()) {
412+ Name filename () const in (base.isFile()) {
368413 return _filename;
369414 }
370415
371416 @property
372- auto directory () const in (base.isFile()) {
417+ Name directory () const in (base.isFile()) {
373418 return _directory;
374419 }
375420
0 commit comments