yodamaster / include-what-you-use

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

forward declaring classes used in template functions that do not allow incomplete types #175

Open GoogleCodeExporter opened 9 years ago

GoogleCodeExporter commented 9 years ago
clang/llvm/iwyu trunk (3.7)

iwyu forward declares classes used in template functions that do not allow 
incomplete types (e.g., std::pair<_T1,_T2>).  This is similar to the problem of 
forward declaring classes used in catch().

If I have a class defined in a namespace in 

Example below of a header file:
#include <string>
#include "variant.hpp" //declares ESM::Variant
namespace ESM
{
    class ESMReader;
    class ESMWriter;
    struct Locals
    {
        std::vector<std::pair<std::string, Variant> > mVariables;
        void load (ESMReader &esm);
        void save (ESMWriter &esm) const;
    };
}

iwyu says:
components/esm/locals.hpp should add these lines:
#include <utility>                      // for pair
namespace ESM { class Variant; }
//end of file

components/esm/locals.hpp should remove these lines:
- #include "variant.hpp"  // lines 7-7

The full include-list for components/esm/locals.hpp:
#include <string>                       // for string
#include <utility>                      // for pair
#include <vector>                       // for vector
namespace ESM { class ESMReader; }  // lines 11-11
namespace ESM { class ESMWriter; }  // lines 12-12
namespace ESM { class Variant; }
end file

However, replacing #include "variant.hpp" with namespace ESM { class Variant; } 
causes the error:
bits/stl_pair.h:102:11: error: field has incomplete type 'ESM::Variant'

since std::pair can't take incomplete types.

thank you! (btw, I'm not a c++ guy, CS, or would even call myself a programmer, 
so please excuse any mistakes in my reports)

Original issue reported on code.google.com by showard...@gmail.com on 7 Feb 2015 at 5:41

GoogleCodeExporter commented 9 years ago
Don't know whether this is related, but might also happen with member functions 
of template classes:
error: member access into incomplete type

Example, a member function is defined in a header file:

//headerfile
namespace somenamespace
{
  template <class T> //don't know if this only happens for template classes
  class Store : public StoreBase
  {
    public:
      void write (ESM::ESMWriter& writer) const
      {
        writer.startRecord (T::sRecordId);
      }
   }
}

iwyu says i should add
namespace ESM { class ESMWriter; }

and should remove:
#include <components/esm/esmwriter.hpp>  // lines 10-10

which then would cause
error: member access into incomplete type

(full example file here: 
https://github.com/OpenMW/openmw/blob/master/apps/openmw/mwworld/store.hpp)

Original comment by showard...@gmail.com on 7 Feb 2015 at 5:58

GoogleCodeExporter commented 9 years ago
Thanks for the bug report, showard314. I was able to reproduce it with 
`std::vector<std::pair<int, IndirectClass> >`. By the way, just `std::pair<int, 
IndirectClass>` requires full use of IndirectClass. My current guess is that we 
correctly detect we need full use of std::pair, but we don't check full use, 
forward-declare use for std::pair template arguments.

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

GoogleCodeExporter commented 9 years ago
I just came across this same bug*, but I'd just like to note that when the 
class has both vector<pair<string,string>> and plain string member variables, 
it still recommends to use iosfwd instead of string. Is there any known 
workaround for this?

Original comment by douwegel...@gmail.com on 27 Mar 2015 at 1:25

GoogleCodeExporter commented 9 years ago
It's not helpful, but I think the problem with iosfwd is issue #80, especially 
if you are using libc++, not libstdc++.  And unfortunately I don't know any 
workarounds for it.

Original comment by vsap...@gmail.com on 31 Mar 2015 at 6:10