gbjie / include-what-you-use

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

fstream include removed while required #90

Open GoogleCodeExporter opened 9 years ago

GoogleCodeExporter commented 9 years ago
What is the expected output? What do you see instead?

I run include-what-you-use on a large source file containing Google Test test 
cases.
On this particular file, there is a class extending 'testing::Test', which has 
protected members of type 'ifstream'. As a result, an include is needed: 
'#include <fstream>'

However, IWYU suggests removing the '<fstream>' include, and I can't find out 
why.
I've created a smaller test case.

What version of the product are you using? On what operating system?
I'm afraid I'm using an older IWYU version (revision 352), since I had issues 
compiling the newer version.
I'm running Ubuntu Linux 64-bit.

Please provide any additional information below.

Original issue reported on code.google.com by mathias....@gmail.com on 4 Jan 2013 at 4:03

Attachments:

GoogleCodeExporter commented 9 years ago
Note: in the smaller test case, '<fstream>' is not present. It's needed for 
compilation, but IWYU does not suggest to add it.

If you add '#include <fstream>', IWYU suggests to remove it.

Original comment by mathias....@gmail.com on 4 Jan 2013 at 4:04

GoogleCodeExporter commented 9 years ago
I can repro with HEAD revision on Windows/MSVC (with Microsoft's STL.)

It seems like the relationships among the iostream headers are less than clear.

In my environment, IWYU identifies std::ifstream as being defined in <iosfwd> 
and then cross-references your includes with all <iosfwd> equivalents (e.g. 
<iostream>, <streambuf>, <ios>, etc.) header mapping until it finds <iostream>. 
Since you already have <iostream> included, it concludes that <fstream> is not 
necessary.

I think the mappings here are sub-par, but I'm not sure how to better express 
them.

I managed to work around this issue by adding a *symbol* mapping from 
std::ifstream to <fstream>, but it's not 100% right, because sometimes 
std::ifstream should map to <iosfwd>. Adding both causes the problem to 
reappear.

Can you try and catch up to the latest version of Clang/LLVM/IWYU and log any 
problems as a separate issue? It's much easier for you to tweak these things in 
later revs of IWYU.

Original comment by kim.gras...@gmail.com on 5 Jan 2013 at 9:52

GoogleCodeExporter commented 9 years ago
I have not yet been able to try with the latest Clang and IWYU (takes a bit of 
time), but I have noticed another similar issue with my current version.
The '<sstream>' header is also removed in one of my source files, while it's 
needed for ostringstream.

Original comment by mathias....@gmail.com on 8 Jan 2013 at 10:46

GoogleCodeExporter commented 9 years ago
clang/llvm/iwyu 3.5 and it still exists, both fstream and sstream are being 
removed while it's needed for std::ostringstream

Original comment by showard...@gmail.com on 4 Feb 2015 at 2:17

GoogleCodeExporter commented 9 years ago
Here's a little more detail:
error: implicit instantiation of undefined template 
'std::basic_ostringstream<char, std::char_traits<char>, std::allocator<char> >'
        std::ostringstream retval;

Original comment by showard...@gmail.com on 4 Feb 2015 at 2:20

GoogleCodeExporter commented 9 years ago
Here's a little more detail about when <sstream> was removed
error: implicit instantiation of undefined template 
'std::basic_ostringstream<char, std::char_traits<char>, std::allocator<char> >'
        std::ostringstream retval;

In this case, <fstream> was removed and <sstream> was added 
 error: invalid operands to binary expression ('std::ofstream' (aka 'basic_ofstream<char>') and 'const std::string'
      (aka 'const basic_string<char>'))
 stream << indentation ;

Original comment by showard...@gmail.com on 4 Feb 2015 at 5:05

GoogleCodeExporter commented 9 years ago
Thanks for the added detail.

This seems to be one of those tricky mapping problems, where nothing is really 
right or wrong. For example, std::ostream might be validly provided by 
<fstream>, <ostream>, <iostream> or <iosfwd> depending on... well, I'm not sure 
exactly what :-)

There is some kind of mapping hierarchy set up inside IWYU to match an old 
libstdc++, but I'm not sure if this can be properly expressed with the current 
mapping mechanisms (it could be that we need some way to express "header to use 
for forward-decl uses" for <iosfwd>, for example.)

Original comment by kim.gras...@gmail.com on 4 Feb 2015 at 8:12