From 2587c22c1c247b65b086a130e3acbc31e54e2aa4 Mon Sep 17 00:00:00 2001 From: Dennis Korpel Date: Sat, 25 Jan 2025 00:37:39 +0100 Subject: [PATCH] Shrink Loc from 12 to 4 bytes --- compiler/src/dmd/cparse.d | 1 - compiler/src/dmd/dmodule.d | 4 +- compiler/src/dmd/dstruct.d | 2 +- compiler/src/dmd/dsymbolsem.d | 41 ++--- compiler/src/dmd/expressionsem.d | 5 +- compiler/src/dmd/frontend.h | 45 +++--- compiler/src/dmd/globals.h | 23 +-- compiler/src/dmd/identifier.d | 11 +- compiler/src/dmd/lexer.d | 38 +++-- compiler/src/dmd/location.d | 242 +++++++++++++++++++++--------- compiler/src/dmd/mars.d | 2 +- compiler/src/dmd/statementsem.d | 5 +- compiler/src/dmd/typesem.d | 5 +- compiler/src/tests/cxxfrontend.cc | 13 +- 14 files changed, 259 insertions(+), 178 deletions(-) diff --git a/compiler/src/dmd/cparse.d b/compiler/src/dmd/cparse.d index 354d83bd4ba4..af2b190abbdf 100644 --- a/compiler/src/dmd/cparse.d +++ b/compiler/src/dmd/cparse.d @@ -6324,7 +6324,6 @@ final class CParser(AST) : Parser!AST while (*p) ++p; ++p; // advance to start of next line - scanloc.linnum = scanloc.linnum + 1; } if (newSymbols.length) diff --git a/compiler/src/dmd/dmodule.d b/compiler/src/dmd/dmodule.d index f26c5812ddf9..d23c54f94c6e 100644 --- a/compiler/src/dmd/dmodule.d +++ b/compiler/src/dmd/dmodule.d @@ -807,7 +807,7 @@ extern (C++) final class Module : Package checkCompiledImport(); members = p.parseModule(); assert(!p.md); // C doesn't have module declarations - numlines = p.scanloc.linnum; + numlines = p.linnum; } else { @@ -831,7 +831,7 @@ extern (C++) final class Module : Package checkCompiledImport(); members = p.parseModuleContent(); - numlines = p.scanloc.linnum; + numlines = p.linnum; } /* The symbol table into which the module is to be inserted. diff --git a/compiler/src/dmd/dstruct.d b/compiler/src/dmd/dstruct.d index 9a9058f61dc8..d0b10a5d10bf 100644 --- a/compiler/src/dmd/dstruct.d +++ b/compiler/src/dmd/dstruct.d @@ -119,7 +119,7 @@ extern (C++) class StructDeclaration : AggregateDeclaration extern (D) this(const ref Loc loc, Identifier id, bool inObject) { super(loc, id); - zeroInit = false; // assume false until we do semantic processing + // zeroInit = false; // assume false until we do semantic processing ispod = ThreeState.none; // For forward references type = new TypeStruct(this); diff --git a/compiler/src/dmd/dsymbolsem.d b/compiler/src/dmd/dsymbolsem.d index c7fb26a9da1a..5e42d299bfa0 100644 --- a/compiler/src/dmd/dsymbolsem.d +++ b/compiler/src/dmd/dsymbolsem.d @@ -1848,8 +1848,9 @@ private extern(C++) final class DsymbolSemanticVisitor : Visitor buf.writeByte(0); const str = buf.extractSlice()[0 .. len]; const bool doUnittests = global.params.parsingUnittestsRequired(); - auto loc = adjustLocForMixin(str, cd.loc, global.params.mixinOut); - scope p = new Parser!ASTCodegen(loc, sc._module, str, false, global.errorSink, &global.compileEnv, doUnittests); + scope p = new Parser!ASTCodegen(sc._module, str, false, global.errorSink, &global.compileEnv, doUnittests); + adjustLocForMixin(str, cd.loc, *p.baseLoc, global.params.mixinOut); + p.linnum = p.baseLoc.startLine; p.nextToken(); auto d = p.parseDeclDefs(0); @@ -5920,34 +5921,40 @@ private CallExp doAtomicOp (string op, Identifier var, Expression arg) * Set up loc for a parse of a mixin. Append the input text to the mixin. * Params: * input = mixin text - * loc = location to adjust + * loc = location of expansion + * baseLoc = location to adjust * mixinOut = sink for mixin text data * Returns: * adjusted loc suitable for Parser */ -Loc adjustLocForMixin(const(char)[] input, ref const Loc loc, ref Output mixinOut) +void adjustLocForMixin(const(char)[] input, Loc loc, ref BaseLoc baseLoc, ref Output mixinOut) { - Loc result; if (mixinOut.doOutput) { const lines = mixinOut.bufferLines; writeMixin(input, loc, mixinOut.bufferLines, *mixinOut.buffer); - result = Loc(mixinOut.name.ptr, lines + 2, loc.charnum); + baseLoc.startLine = lines + 2; + baseLoc.filename = mixinOut.name; + return; } - else if (loc.filename) + + SourceLoc sl = SourceLoc(loc); + if (sl.filename.length == 0) { - /* Create a pseudo-filename for the mixin string, as it may not even exist - * in the source file. - */ - auto len = strlen(loc.filename) + 7 + (loc.linnum).sizeof * 3 + 1; - char* filename = cast(char*)mem.xmalloc(len); - snprintf(filename, len, "%s-mixin-%d", loc.filename, cast(int)loc.linnum); - result = Loc(filename, loc.linnum, loc.charnum); + // Rare case of compiler-generated mixin exp, e.g. __xtoHash + baseLoc.filename = ""; + return; } - else - result = loc; - return result; + + /* Create a pseudo-filename for the mixin string, as it may not even exist + * in the source file. + */ + auto len = sl.filename.length + 7 + (sl.linnum).sizeof * 3 + 1; + char* filename = cast(char*) mem.xmalloc(len); + snprintf(filename, len, "%.*s-mixin-%d", cast(int) sl.filename.length, sl.filename.ptr, cast(int) sl.linnum); + baseLoc.startLine = sl.line; + baseLoc.filename = filename.toDString; } /************************************** diff --git a/compiler/src/dmd/expressionsem.d b/compiler/src/dmd/expressionsem.d index 1cf7840d7ad5..12dec2c7922b 100644 --- a/compiler/src/dmd/expressionsem.d +++ b/compiler/src/dmd/expressionsem.d @@ -7654,8 +7654,9 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor const len = buf.length; const str = buf.extractChars()[0 .. len]; const bool doUnittests = global.params.parsingUnittestsRequired(); - auto loc = adjustLocForMixin(str, exp.loc, global.params.mixinOut); - scope p = new Parser!ASTCodegen(loc, sc._module, str, false, global.errorSink, &global.compileEnv, doUnittests); + scope p = new Parser!ASTCodegen(sc._module, str, false, global.errorSink, &global.compileEnv, doUnittests); + adjustLocForMixin(str, exp.loc, *p.baseLoc, global.params.mixinOut); + p.linnum = p.baseLoc.startLine; p.nextToken(); //printf("p.loc.linnum = %d\n", p.loc.linnum); diff --git a/compiler/src/dmd/frontend.h b/compiler/src/dmd/frontend.h index ad7afc3ab8e2..e58f7ca9ff03 100644 --- a/compiler/src/dmd/frontend.h +++ b/compiler/src/dmd/frontend.h @@ -380,28 +380,23 @@ enum class MessageStyle : uint8_t struct Loc final { private: - uint32_t _linnum; - uint32_t _charnum; - uint32_t fileIndex; + uint32_t index; public: static bool showColumns; static MessageStyle messageStyle; static void set(bool showColumns, MessageStyle messageStyle); - Loc(const char* filename, uint32_t linnum, uint32_t charnum); uint32_t charnum() const; - uint32_t charnum(uint32_t num); uint32_t linnum() const; - uint32_t linnum(uint32_t num); const char* filename() const; - void filename(const char* name); const char* toChars(bool showColumns = Loc::showColumns, MessageStyle messageStyle = Loc::messageStyle) const; bool equals(const Loc& loc) const; Loc() : - _linnum(), - _charnum(), - fileIndex() + index(0u) { } + Loc(uint32_t index) : + index(index) + {} }; enum class PASS : uint8_t @@ -5402,23 +5397,23 @@ struct UnionExp final private: union _AnonStruct_u { - char exp[30LLU]; - char integerexp[40LLU]; - char errorexp[30LLU]; + char exp[22LLU]; + char integerexp[32LLU]; + char errorexp[22LLU]; char realexp[48LLU]; char complexexp[64LLU]; - char symoffexp[64LLU]; - char stringexp[51LLU]; - char arrayliteralexp[48LLU]; - char assocarrayliteralexp[56LLU]; - char structliteralexp[72LLU]; - char compoundliteralexp[40LLU]; - char nullexp[30LLU]; - char dotvarexp[49LLU]; - char addrexp[40LLU]; - char indexexp[58LLU]; - char sliceexp[65LLU]; - char vectorexp[53LLU]; + char symoffexp[56LLU]; + char stringexp[43LLU]; + char arrayliteralexp[40LLU]; + char assocarrayliteralexp[48LLU]; + char structliteralexp[64LLU]; + char compoundliteralexp[32LLU]; + char nullexp[22LLU]; + char dotvarexp[41LLU]; + char addrexp[32LLU]; + char indexexp[50LLU]; + char sliceexp[57LLU]; + char vectorexp[45LLU]; }; #pragma pack(pop) diff --git a/compiler/src/dmd/globals.h b/compiler/src/dmd/globals.h index 6dd4be4b0a01..e0e4a42bf268 100644 --- a/compiler/src/dmd/globals.h +++ b/compiler/src/dmd/globals.h @@ -417,9 +417,12 @@ typedef unsigned long long uinteger_t; struct Loc { private: - unsigned _linnum; - unsigned _charnum; - unsigned fileIndex; + +#if defined(__linux__) && defined(__i386__) + unsigned int dummy; +#endif + + unsigned int index; public: static void set(bool showColumns, MessageStyle messageStyle); @@ -428,24 +431,12 @@ struct Loc Loc() { - _linnum = 0; - _charnum = 0; - fileIndex = 0; - } - - Loc(const char *filename, unsigned linnum, unsigned charnum) - { - this->linnum(linnum); - this->charnum(charnum); - this->filename(filename); + index = 0; } uint32_t charnum() const; - uint32_t charnum(uint32_t num); uint32_t linnum() const; - uint32_t linnum(uint32_t num); const char *filename() const; - void filename(const char *name); const char *toChars( bool showColumns = Loc::showColumns, diff --git a/compiler/src/dmd/identifier.d b/compiler/src/dmd/identifier.d index 74be1beb29f9..4fd7e7035748 100644 --- a/compiler/src/dmd/identifier.d +++ b/compiler/src/dmd/identifier.d @@ -221,12 +221,13 @@ nothrow: extern (D) static Identifier generateIdWithLoc(string prefix, const ref Loc loc, string parent = "") { // generate `_L_C` + auto sl = SourceLoc(loc); OutBuffer idBuf; idBuf.writestring(prefix); idBuf.writestring("_L"); - idBuf.print(loc.linnum); + idBuf.print(sl.line); idBuf.writestring("_C"); - idBuf.print(loc.charnum); + idBuf.print(sl.column); /** * Make sure the identifiers are unique per filename, i.e., per module/mixin @@ -244,13 +245,13 @@ nothrow: * directly, but that would unnecessary lengthen symbols names. See issue: * https://issues.dlang.org/show_bug.cgi?id=23722 */ - static struct Key { Loc loc; string prefix; string parent; } + static struct Key { uint fileOffset; string prefix; string parent; } __gshared uint[Key] counters; static if (__traits(compiles, counters.update(Key.init, () => 0u, (ref uint a) => 0u))) { // 2.082+ - counters.update(Key(loc, prefix, parent), + counters.update(Key(loc.fileOffset, prefix, parent), () => 1u, // insertion (ref uint counter) // update { @@ -262,7 +263,7 @@ nothrow: } else { - const key = Key(loc, prefix, parent); + const key = Key(loc.fileOffset, prefix, parent); if (auto pCounter = key in counters) { idBuf.writestring("_"); diff --git a/compiler/src/dmd/lexer.d b/compiler/src/dmd/lexer.d index 406829d8257e..210b014e0f50 100644 --- a/compiler/src/dmd/lexer.d +++ b/compiler/src/dmd/lexer.d @@ -34,11 +34,6 @@ import dmd.tokens; nothrow: -version (DMDLIB) -{ - version = LocOffset; -} - /*********************************************************** * Values to use for various magic identifiers */ @@ -68,8 +63,10 @@ class Lexer { private __gshared OutBuffer stringbuffer; + BaseLoc* baseLoc; // Used to generate `scanloc`, which is just an index into this data structure Loc scanloc; // for error messages Loc prevloc; // location of token before current + int linnum; // current line number const(char)* p; // current character @@ -132,10 +129,11 @@ class Lexer ErrorSink errorSink, const CompileEnv* compileEnv) scope { - scanloc = Loc(filename, 1, 1); // debug printf("Lexer::Lexer(%p)\n", base); // debug printf("lexer.filename = %s\n", filename); token = Token.init; + this.baseLoc = newBaseLoc(filename, endoffset); + this.linnum = 1; this.base = base; this.end = base + endoffset; p = base + begoffset; @@ -225,7 +223,9 @@ class Lexer tokenizeNewlines = true; inTokenStringConstant = 0; lastDocLine = 0; - scanloc = Loc("#defines", 1, 1); + + baseLoc = newBaseLoc("#defines", slice.length); + scanloc = baseLoc.getLoc(0); } /********************************** @@ -319,7 +319,7 @@ class Lexer */ final void scan(Token* t) { - const lastLine = scanloc.linnum; + const lastLine = linnum; Loc startLoc; t.blockComment = null; t.lineComment = null; @@ -897,7 +897,7 @@ class Lexer { // if /** but not /**/ getDocComment(t, lastLine == startLoc.linnum, startLoc.linnum - lastDocLine > 1); - lastDocLine = scanloc.linnum; + lastDocLine = linnum; } continue; case '/': // do // style comments @@ -925,7 +925,7 @@ class Lexer if (doDocComment && t.ptr[2] == '/') { getDocComment(t, lastLine == startLoc.linnum, startLoc.linnum - lastDocLine > 1); - lastDocLine = scanloc.linnum; + lastDocLine = linnum; } p = end; t.loc = loc(); @@ -957,7 +957,7 @@ class Lexer if (doDocComment && t.ptr[2] == '/') { getDocComment(t, lastLine == startLoc.linnum, startLoc.linnum - lastDocLine > 1); - lastDocLine = scanloc.linnum; + lastDocLine = linnum; } p++; endOfLine(); @@ -1029,7 +1029,7 @@ class Lexer { // if /++ but not /++/ getDocComment(t, lastLine == startLoc.linnum, startLoc.linnum - lastDocLine > 1); - lastDocLine = scanloc.linnum; + lastDocLine = linnum; } continue; } @@ -3154,9 +3154,7 @@ class Lexer final Loc loc() @nogc { - scanloc.charnum = cast(ushort)(1 + p - line); - version (LocOffset) - scanloc.fileOffset = cast(uint)(p - base); + scanloc = baseLoc.getLoc(cast(uint) (p - base)); return scanloc; } @@ -3251,7 +3249,6 @@ class Lexer */ final void poundLine(ref Token tok, bool linemarker) { - auto linnum = this.scanloc.linnum; const(char)* filespec = null; bool flags; @@ -3288,9 +3285,7 @@ class Lexer case TOK.endOfLine: if (!inTokenStringConstant) { - this.scanloc.linnum = linnum; - if (filespec) - this.scanloc.filename = filespec; + baseLoc.addSubstitution(cast(uint) (p - base), filespec, linnum); } return; case TOK.file: @@ -3589,10 +3584,11 @@ class Lexer /************************** * `p` should be at start of next line */ - private void endOfLine() @nogc @safe + private void endOfLine() @safe { - scanloc.linnum = scanloc.linnum + 1; + linnum += 1; line = p; + baseLoc.newLine(cast(uint)(p - base)); } /**************************** diff --git a/compiler/src/dmd/location.d b/compiler/src/dmd/location.d index 75cd068a1de7..f2bc205389c0 100644 --- a/compiler/src/dmd/location.d +++ b/compiler/src/dmd/location.d @@ -18,11 +18,6 @@ import dmd.root.array; import dmd.root.filename; import dmd.root.string: toDString; -version (DMDLIB) -{ - version = LocOffset; -} - /// How code locations are formatted for diagnostic reporting enum MessageStyle : ubyte { @@ -38,19 +33,19 @@ debug info etc. */ struct Loc { - private uint _linnum; - private uint _charnum; - private uint fileIndex; // index into filenames[], starting from 1 (0 means no filename) - version (LocOffset) - uint fileOffset; /// utf8 code unit index relative to start of file, starting from 0 + // https://github.com/dlang/dmd/pull/20777#issuecomment-2614128849 + static if (size_t.sizeof == 4) version(linux) + { + uint dummy; + } + + private uint index = 0; // offset into lineTable[] static immutable Loc initial; /// use for default initialization of const ref Loc's extern (C++) __gshared bool showColumns; extern (C++) __gshared MessageStyle messageStyle; - __gshared Array!(const(char)*) filenames; - nothrow: /******************************* @@ -65,45 +60,33 @@ nothrow: this.messageStyle = messageStyle; } - extern (C++) this(const(char)* filename, uint linnum, uint charnum) @safe + static Loc singleFilename(const char* filename) { - this._linnum = linnum; - this._charnum = charnum; - this.filename = filename; + Loc result; + locFileTable ~= BaseLoc(filename.toDString, locIndex, 0, [0]); + result.index = locIndex++; + return result; } /// utf8 code unit index relative to start of line, starting from 1 extern (C++) uint charnum() const @nogc @safe { - return _charnum; - } - - /// ditto - extern (C++) uint charnum(uint num) @nogc @safe - { - return _charnum = num; + return SourceLoc(this).column; } /// line number, starting from 1 - extern (C++) uint linnum() const @nogc @safe - { - return _linnum; - } - - /// ditto - extern (C++) uint linnum(uint num) @nogc @safe + extern (C++) uint linnum() const @nogc @trusted { - return _linnum = num; + return SourceLoc(this).line; } /// Advance this location to the first column of the next line void nextLine() { - if (this._linnum) - { - this._linnum++; - this.charnum = 0; - } + const i = fileTableIndex(this.index); + const j = locFileTable[i].getLineIndex(this.index - locFileTable[i].startIndex); + if (j + 1 < locFileTable[i].lines.length) + index = locFileTable[i].startIndex + locFileTable[i].lines[j + 1]; } /*** @@ -111,25 +94,7 @@ nothrow: */ extern (C++) const(char)* filename() const @nogc { - return fileIndex ? filenames[fileIndex - 1] : null; - } - - /*** - * Set file name for this location - * Params: - * name = file name for location, null for no file name - */ - extern (C++) void filename(const(char)* name) @trusted - { - if (name) - { - //printf("setting %s\n", name); - filenames.push(name); - fileIndex = cast(uint)filenames.length; - assert(fileIndex, "internal compiler error: file name index overflow"); - } - else - fileIndex = 0; + return SourceLoc(this).filename.ptr; // _filename; } extern (C++) const(char)* toChars( @@ -139,6 +104,12 @@ nothrow: return SourceLoc(this).toChars(showColumns, messageStyle); } + /// Returns: byte offset into source file + uint fileOffset() const + { + return SourceLoc(this).fileOffset; + } + /** * Checks for equivalence by comparing the filename contents (not the pointer) and character location. * @@ -165,23 +136,13 @@ nothrow: */ extern (D) bool opEquals(ref const(Loc) loc) const @trusted nothrow @nogc { - import core.stdc.string : strcmp; - - return charnum == loc.charnum && - linnum == loc.linnum && - (filename == loc.filename || - (filename && loc.filename && strcmp(filename, loc.filename) == 0)); + return this.index == loc.index; } /// ditto extern (D) size_t toHash() const @trusted nothrow { - import dmd.root.string : toDString; - - auto hash = hashOf(linnum); - hash = hashOf(charnum, hash); - hash = hashOf(filename.toDString, hash); - return hash; + return hashOf(this.index); } /****************** @@ -190,7 +151,7 @@ nothrow: */ bool isValid() const pure @safe { - return fileIndex != 0; + return this.index != 0; } } @@ -252,23 +213,27 @@ struct SourceLoc 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 // aliases for backwards compatibility alias linnum = line; alias charnum = column; - this(const(char)[] filename, uint line, uint column) nothrow + this(const(char)[] filename, uint line, uint column, uint fileOffset = 0) nothrow @nogc pure @safe { this.filename = filename; this.line = line; this.column = column; + this.fileOffset = fileOffset; } - this(Loc loc) nothrow + this(Loc loc) nothrow @nogc @trusted { - this.filename = loc.filename.toDString(); - this.line = loc.linnum; - this.column = loc.charnum; + if (loc.index == 0 || locFileTable.length == 0) + return; + + const i = fileTableIndex(loc.index); + this = locFileTable[i].getSourceLoc(loc.index - locFileTable[i].startIndex); } extern (C++) const(char)* toChars( @@ -284,4 +249,135 @@ struct SourceLoc { return this.filename == other.filename && this.line == other.line && this.column == other.column; } + +} + +private size_t fileTableIndex(uint index) nothrow @nogc +{ + // To speed up linear find, we cache the last hit and compare that first, + // since usually we stay in the same file for some time when resolving source locations. + // If it's a differnet file now, either scan forwards / backwards + __gshared size_t lastI = 0; // index of last found hit + + size_t i = lastI; + if (index >= locFileTable[i].startIndex) + { + while (i + 1 < locFileTable.length && index >= locFileTable[i+1].startIndex) + i++; + } + else + { + while (index < locFileTable[i].startIndex) + i--; + } + + lastI = i; + return i; } + +/** + * Create a new source location map for a file + * Params: + * filename = source file name + * size = space to reserve for locations, equal to the file size in bytes + * Returns: new BaseLoc + */ +BaseLoc* newBaseLoc(const(char)* filename, size_t size) nothrow +{ + locFileTable ~= BaseLoc(filename.toDString, locIndex, 1, [0]); + // Careful: the endloc of a funcdeclaration can + // be one past the very last byte in the file, so account for that + locIndex += size + 1; + return &locFileTable[$ - 1]; +} + +/// Mapping from byte offset into source file to line/column numbers +struct BaseLoc +{ +@safe nothrow: + + const(char)[] filename; // Source file name + uint startIndex; // Subtract this from Loc.index to get file offset + int startLine = 1; // Line number at index 0 + uint[] lines; // For each line, the file offset at which it starts + BaseLoc[] substitutions; // Substitutions from #line / #file directives + + /// Register that a new line starts at `offset` + void newLine(uint offset) + { + lines ~= offset; + } + + Loc getLoc(uint offset) @nogc + { + Loc result; + // import std.stdio; debug writeln(startIndex, " + ", offset, " = ", startIndex + offset); + result.index = startIndex + offset; + return result; + } + + /// Handles #file and #line directives + void addSubstitution(uint offset, const(char)* filename, uint linnum) @system + { + auto fname = filename.toDString; + if (fname.length == 0 && substitutions.length > 0) + fname = substitutions[$ - 1].filename; + substitutions ~= BaseLoc(fname, offset, cast(int) (linnum - lines.length + startLine - 2)); + } + + /// Returns: `loc` modified by substitutions from #file / #line directives + SourceLoc substitute(SourceLoc loc, uint offset) @nogc + { + // printf("substitutions: %d\n", cast(int) substitutions.length); + size_t latest = -1; + foreach (i, ref sub; substitutions) + { + if (offset >= sub.startIndex) + latest = i; + else + break; + } + if (latest != -1) + { + if (substitutions[latest].filename.length > 0) + loc.filename = substitutions[latest].filename; + loc.linnum += substitutions[latest].startLine; + } + return loc; + } + + // Resolve an offset into this file to a filename + line + column + private SourceLoc getSourceLoc(uint offset) @nogc + { + const i = getLineIndex(offset); + const sl = SourceLoc(filename, cast(int) (i + startLine), cast(int) (1 + offset - lines[i]), offset); + return substitute(sl, offset); + } + + // Binary search the index in this.lines corresponding to `offset` + private size_t getLineIndex(uint offset) @nogc + { + size_t lo = 0; + size_t hi = lines.length + -1; + size_t mid = 0; + while (lo <= hi) + { + mid = lo + (hi - lo) / 2; + if (lines[mid] <= offset) + { + if (mid == lines.length - 1 || lines[mid + 1] > offset) + return mid; + + lo = mid + 1; + } + else + { + hi = mid - 1; + } + } + assert(0); + } +} + +private __gshared uint locIndex = 1; // Index of start of the file +private __gshared BaseLoc[] locFileTable; diff --git a/compiler/src/dmd/mars.d b/compiler/src/dmd/mars.d index 0bad6027c7b3..9f0f3ac412a1 100644 --- a/compiler/src/dmd/mars.d +++ b/compiler/src/dmd/mars.d @@ -1801,7 +1801,7 @@ bool createModule(const(char)* file, ref Strings libmodules, const ref Target ta } const(char)[] p = FileName.name(file.toDString()); // strip path const(char)[] ext = FileName.ext(p); - Loc loc = Loc(file, 0, 0); + Loc loc = Loc.singleFilename(file); if (!ext) { if (!p.length) diff --git a/compiler/src/dmd/statementsem.d b/compiler/src/dmd/statementsem.d index 6bbc1a9b28eb..efc8c3693446 100644 --- a/compiler/src/dmd/statementsem.d +++ b/compiler/src/dmd/statementsem.d @@ -4835,8 +4835,9 @@ private Statements* flatten(Statement statement, Scope* sc) buf.writeByte(0); const str = buf.extractSlice()[0 .. len]; const bool doUnittests = global.params.parsingUnittestsRequired(); - auto loc = adjustLocForMixin(str, cs.loc, global.params.mixinOut); - scope p = new Parser!ASTCodegen(loc, sc._module, str, false, global.errorSink, &global.compileEnv, doUnittests); + scope p = new Parser!ASTCodegen(sc._module, str, false, global.errorSink, &global.compileEnv, doUnittests); + adjustLocForMixin(str, cs.loc, *p.baseLoc, global.params.mixinOut); + p.linnum = p.baseLoc.startLine; p.nextToken(); auto a = new Statements(); diff --git a/compiler/src/dmd/typesem.d b/compiler/src/dmd/typesem.d index 65d267f155a3..7cc5e55dd1e8 100644 --- a/compiler/src/dmd/typesem.d +++ b/compiler/src/dmd/typesem.d @@ -7930,8 +7930,9 @@ RootObject compileTypeMixin(TypeMixin tm, ref const Loc loc, Scope* sc) buf.writeByte(0); const str = buf.extractSlice()[0 .. len]; const bool doUnittests = global.params.parsingUnittestsRequired(); - auto locm = adjustLocForMixin(str, loc, global.params.mixinOut); - scope p = new Parser!ASTCodegen(locm, sc._module, str, false, global.errorSink, &global.compileEnv, doUnittests); + scope p = new Parser!ASTCodegen(sc._module, str, false, global.errorSink, &global.compileEnv, doUnittests); + adjustLocForMixin(str, loc, *p.baseLoc, global.params.mixinOut); + p.linnum = p.baseLoc.startLine; p.nextToken(); //printf("p.loc.linnum = %d\n", p.loc.linnum); diff --git a/compiler/src/tests/cxxfrontend.cc b/compiler/src/tests/cxxfrontend.cc index b586696da750..6cfc23139ff2 100644 --- a/compiler/src/tests/cxxfrontend.cc +++ b/compiler/src/tests/cxxfrontend.cc @@ -391,16 +391,9 @@ void test_types() void test_location() { - Loc loc1 = Loc("test.d", 24, 42); - assert(loc1.equals(Loc("test.d", 24, 42))); - assert(strcmp(loc1.toChars(true, MessageStyle::digitalmars), "test.d(24,42)") == 0); - assert(strcmp(loc1.toChars(true, MessageStyle::gnu), "test.d:24:42") == 0); - - assert(strcmp(loc1.toChars(), "test.d(24)") == 0); - Loc::set(true, MessageStyle::digitalmars); - assert(strcmp(loc1.toChars(), "test.d(24,42)") == 0); - Loc::set(false, MessageStyle::gnu); - assert(strcmp(loc1.toChars(), "test.d:24") == 0); + Loc loc = Loc(); + assert(strcmp(loc.toChars(true, MessageStyle::digitalmars), "") == 0); + assert(strcmp(loc.toChars(true, MessageStyle::gnu), "") == 0); } /**********************************/