Using ddmd to tighten up imports

Joakim via Digitalmars-d digitalmars-d at puremagic.com
Thu Dec 25 11:09:31 PST 2014


I wanted a tool to help me find imported symbols, so that I can 
import a module and use whatever I want from it initially (import 
std.stdio;) then go back and selectively add the symbols I 
actually used later (import std.stdio : writefln, writeln;).  
Using ddmd to dump this info seemed enticing, so I contacted 
Daniel and got him to push his latest ddmd port from a few weeks 
ago:

https://github.com/yebblies/dmd/tree/newmagic

This new ddmd branch is only tested on Win32: it sometimes 
segfaults in codegen on Linux/x86, but the frontend is all that's 
needed so that's fine.

I looked through the ddmd source and found the spot in dsymbol.d 
where the imported symbols are resolved.  I dumped those resolved 
symbols and disabled codegen in mars.d, so that I don't have to 
see any segfaults.  The tiny patch is here:

https://gist.github.com/joakim-noah/09cf49bee3d82b03a54f

There's no real reason to use ddmd- regular dmd can be used 
instead with a slightly modified version of this patch- but I'd 
like to see others use the ddmd frontend to write more tools like 
this, so I'll detail the steps I took to build and use ddmd.

First, I pulled Dan's branch into my local dmd repo and checked 
it out:

git remote add -t newmagic ddmd 
https://github.com/yebblies/dmd.git
git fetch ddmd
git checkout -b newmagic ddmd/newmagic

Then, I built dmd and ddmd, after making sure I had a dmd.conf 
and phobos built, as ddmd relies on phobos:

make -f posix.mak
cd src
make -f posix.mak ddmd

I applied the above patch and rebuilt ddmd:

git apply import.patch
make -f posix.mak ddmd

Finally, I ran it on a sample file:

./ddmd ../samples/sieve.d

That dumps out 2054 instances of symbols that are resolved from 
either the sample file or all the other modules it imports.  To 
see only what the sample file imports:

./ddmd ../samples/sieve.d | grep "from ../samples/sieve.d"

found writefln from ../samples/sieve.d:12 in 
./../../phobos/std/stdio.d:3063 - 'writefln(T...)(T args)'
found writefln from ../samples/sieve.d:39 in 
./../../phobos/std/stdio.d:3063 - 'writefln(T...)(T args)'

That shows two invocations of writefln from sieve.d and where 
they were imported from.

I tried running this modified ddmd on std.stdio (ddmd -c 
../../phobos/std/stdio.d) and more narrowly scoping some of the 
imports, PR in progress:

https://github.com/D-Programming-Language/phobos/pull/2809

However, I found that the more narrowly scoped imports in 
std.stdio would compile fine with dmd, but the entire phobos 
would not.  Turns out the problem is that imported symbols from 
templates are not searched for if the module is compiled without 
instantiating them, so I got around this by building the unit 
tests:

./ddmd -unittest ../../phobos/std/stdio.d | grep "from 
../../phobos/std/stdio.d"

That found many more resolved symbols- 764 instances of resolved 
symbol imports as opposed to 156 when simply compiling the 
module- and after updating std.stdio with those new symbols, I 
had no problem building phobos or running its unit tests.

Obviously, this simple output can be cleaned up and made much 
more user-friendly and a lot more such tools can be built using 
the ddmd frontend.  Another cleanup I'd like to use is to write 
code with auto types everywhere, then employ a similar tool to 
replace them with the actual inferred types, saving me from 
looking up the types.

I hope this spurs others to try building similar tools based on 
the ddmd frontend, happy ddmd spelunking!


More information about the Digitalmars-d mailing list