zcourts / include-what-you-use

Automatically exported from code.google.com/p/include-what-you-use
Other
0 stars 0 forks source link

using declarations of overloaded functions greedily add unnecessary includes #174

Open GoogleCodeExporter opened 9 years ago

GoogleCodeExporter commented 9 years ago
What steps will reproduce the problem?  Give the *exact* arguments passed
to include-what-you-use, and attach the input source file that gives the
problem (minimal test-cases are much appreciated!)

1. Add a using declaration for something like std::swap

#include <vector>
#include <list>

void use_overload() {  
  std::vector<int> a(10);
  std::vector<int> b(11);
  using std::swap;
  swap(a, b);
}

2. Run IWYU on this file using default options

What is the expected output? What do you see instead?

I expect IWYU to tell me I can remove #include <list>.  Instead I get the 
following output;

using_overload.cc should add these lines:
#include <algorithm>                    // for swap

using_overload.cc should remove these lines:

The full include-list for using_overload.cc:
#include <algorithm>                    // for swap
#include <list>                         // for swap
#include <vector>                       // for swap, vector

What version of the product are you using? On what operating system?

Ubuntu 14.10 / Clang 3.5 / IWYU Svn Rev. 599

Please provide any additional information below.

I tracked down the problem to how IWYU internally handles using declarations.  
What happens is IWYU finds all of the declarations that a using statement could 
be referencing (essentially anything with that name). Those names are then 
added as forward declarable. However, in post processing, IWYU converts all 
function references to needing to be fully included, not forward declarable.  
This makes sense, but it does mean that all overloads of functions accessed 
through a using declaration will always need to be #included.  Attached is a 
test to catch this plus my attempt at a fix.  The fix is outlined as follows;
- Change adding all references of a using declaration from immediate to deferred
- Detect when something is accessed though a using declaration and add it as 
forward declarable.
- If a using declaration is never referenced, arbitrarily add one of the 
symbols it is referencing so that we don't remove all headers it refers to and 
break compilation.

This fix is not small and contains a questionable check at line 2577 of iwyu.cc 
that I think warrants some discussion.

Note:  This patch was made against my github fork, if you want one against svn 
I can do that.

Original issue reported on code.google.com by c.d.glo...@gmail.com on 7 Feb 2015 at 3:55

Attachments:

GoogleCodeExporter commented 9 years ago
Thanks for addressing this issue. I haven't looked at the patch yet and cannot 
tell for sure when will be able to do so. Lack of response doesn't mean your 
work was ignored.

Original comment by vsap...@gmail.com on 10 Feb 2015 at 2:21