From f4e4b7e6ff66ec4d0d2774f309731c03392327cc Mon Sep 17 00:00:00 2001 From: Rainer Schuetze Date: Wed, 21 Aug 2019 08:47:15 +0200 Subject: [PATCH] fix Issue 4372, 982 - CodeView: type of enumerator values reduced to base type in debug info write a forward reference to the enum definition, it is emitted elsewhere --- src/dmd/backend/dcgcv.d | 45 ++++++++++++++++++++++++++++++++++++++++- test/runnable/testpdb.d | 32 +++++++++++++++++++++++++++-- 2 files changed, 74 insertions(+), 3 deletions(-) diff --git a/src/dmd/backend/dcgcv.d b/src/dmd/backend/dcgcv.d index 8d8781fefcd3..c9a8bf58ac57 100644 --- a/src/dmd/backend/dcgcv.d +++ b/src/dmd/backend/dcgcv.d @@ -1736,7 +1736,50 @@ static if (SYMDEB_TDB) } } +else +{ +private uint cv4_fwdenum(type* t) +{ + Symbol* s = t.Ttag; + + if (s.Stypidx) // if reference already generated + return s.Stypidx; // use already existing reference + + // write a forward reference enum record that is enough for the linker to + // fold with original definition from EnumDeclaration + uint bty = dttab4[tybasic(t.Tnext.Tty)]; + const id = prettyident(s); + uint len = config.fulltypes == CV8 ? 14 : 10; + debtyp_t* d = debtyp_alloc(len + cv_stringbytes(id)); + switch (config.fulltypes) + { + case CV8: + TOWORD(d.data.ptr, LF_ENUM_V3); + TOLONG(d.data.ptr + 2, 0); // count + TOWORD(d.data.ptr + 4, 0x80); // property : forward reference + TOLONG(d.data.ptr + 6, bty); // memtype + TOLONG(d.data.ptr + 10, 0); // fieldlist + break; + case CV4: + TOWORD(d.data.ptr,LF_ENUM); + TOWORD(d.data.ptr + 2, 0); // count + TOWORD(d.data.ptr + 4, bty); // memtype + TOLONG(d.data.ptr + 6, 0); // fieldlist + TOWORD(d.data.ptr + 8, 0x80); // property : forward reference + break; + + default: + assert(0); + } + len += cv_namestring(d.data.ptr + len, id); + d.length = 0; // so cv_debtyp() will allocate new + s.Stypidx = cv_debtyp(d); + d.length = cast(ushort)len; // restore length + return s.Stypidx; +} + +} /************************************************ * Return 'calling convention' type of function. */ @@ -2261,7 +2304,7 @@ version (SCPP) } } else - typidx = dttab4[tybasic(t.Tnext.Tty)]; + typidx = cv4_fwdenum(t); break; version (SCPP) diff --git a/test/runnable/testpdb.d b/test/runnable/testpdb.d index 2ddce03eb1c8..6af5c06043c9 100644 --- a/test/runnable/testpdb.d +++ b/test/runnable/testpdb.d @@ -44,9 +44,11 @@ void main(string[] args) S18984 s = test18984(session, globals); test19307(session, globals); - + test19318(session, globals); + testE982(session, globals); + source.Release(); session.Release(); globals.Release(); @@ -222,7 +224,7 @@ int foo19307() return nested()(); } -string toUTF8(wstring ws) +string toUTF8(const(wchar)[] ws) { string s; foreach(dchar c; ws) @@ -333,6 +335,32 @@ void test19318(IDiaSession session, IDiaSymbol globals) assert(off == C19318_px - C19318_capture); } +/////////////////////////////////////////////// +enum E982 +{ + E1, E2, E3 +} + +void testE982(IDiaSession session, IDiaSymbol globals) +{ + E982 ee = E982.E1; + + IDiaSymbol funcSym = searchSymbol(globals, "testpdb.testE982"); + funcSym || assert(false, "testpdb.testE982 not found"); + + string varName = "testpdb.testE982.ee"; + IDiaSymbol varSym = searchSymbol(funcSym, "ee"); + varSym || assert(false, varName ~ " not found"); + + IDiaSymbol varType; + varSym.get_type(&varType) == S_OK || assert(false, varName ~ ": no type"); + BSTR typename; + varType.get_name(&typename) == S_OK || assert(false, varName ~ ": no type name"); + scope(exit) SysFreeString(typename); + wchar[] wtypename = typename[0..wcslen(typename)]; + wcscmp(typename, "testpdb.E982") == 0 || assert(false, varName ~ ": unexpected type name " ~ toUTF8(wtypename)); +} + /////////////////////////////////////////////// import core.stdc.stdio; import core.stdc.wchar_;