zcourts / include-what-you-use

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

Need a way to mark a header as not serving just to include things #74

Open GoogleCodeExporter opened 9 years ago

GoogleCodeExporter commented 9 years ago
What version of the product are you using? On what operating system?
LLVM r160007, iwyu r357, Ubuntu 12.04 LTS x86.

Please provide any additional information below.
In the Mozilla codebase, there are some header files that are actually just a 
series of macros to be used for preprocessor magic, not defining things.  Like 
this:

"""
EDITOR_ATOM(a, "a")
EDITOR_ATOM(abbr, "abbr")
EDITOR_ATOM(acronym, "acronym")
EDITOR_ATOM(address, "address")
EDITOR_ATOM(article, "article")
EDITOR_ATOM(aside, "aside")
...
"""
http://dxr.lanedo.com/mozilla-central/editor/libeditor/base/nsEditPropertyAtomLi
st.h.html

Which is used thus:

"""
#define EDITOR_ATOM(name_, value_) nsIAtom* nsEditProperty::name_ = 0;
#include "nsEditPropertyAtomList.h"
#undef EDITOR_ATOM
...
#define EDITOR_ATOM(name_, value_) NS_STATIC_ATOM_BUFFER(name_##_buffer, value_)
#include "nsEditPropertyAtomList.h"
#undef EDITOR_ATOM
...
#define EDITOR_ATOM(name_, value_) NS_STATIC_ATOM(name_##_buffer, &name_),
#include "nsEditPropertyAtomList.h"
#undef EDITOR_ATOM
"""
http://dxr.lanedo.com/mozilla-central/editor/libeditor/html/nsEditProperty.cpp.h
tml#l14

IWYU tries to move the #include lines around and removes two of the three, 
which obviously breaks everything.  I tried marking the includes with "// IWYU 
pragma: keep", but that only made it keep the third, while it still removed the 
other two.  There needs to be some way to tell it to not touch the line at all 
-- perhaps pragma: keep should do that.

Or if some way already exists, please add it to 
<http://code.google.com/p/include-what-you-use/source/browse/trunk/README.txt?r=
260>.  :)

Original issue reported on code.google.com by a...@aryeh.name on 11 Jul 2012 at 11:27

GoogleCodeExporter commented 9 years ago
> IWYU tries to move the #include lines around and removes two of the three,
> which obviously breaks everything.  I tried marking the includes with "//
> IWYU pragma: keep", but that only made it keep the third, while it still
> removed the other two.  There needs to be some way to tell it to not touch
> the line at all -- perhaps pragma: keep should do that.

I'm experimenting with pragma: keep, and I agree it would be better if it 
caused duplicate #includes to be preserved. Anyone disagree?

I can't think of a way other than an explicit pragma to let IWYU know what's 
going on here.

Original comment by kim.gras...@gmail.com on 13 Jul 2012 at 5:44

GoogleCodeExporter commented 9 years ago
I think the problem is that IWYU doesn't distinguish #include 
"nsEditPropertyAtomList.h". It treats them like interchangeable, but in fact 
they are not. I'd like to fix this problem instead of forcing developers to add 
pragma: keep manually.

Original comment by vsap...@gmail.com on 13 Jul 2012 at 6:39

GoogleCodeExporter commented 9 years ago
Yes, pragma: keep would be a workaround. Maybe there should be a separate issue 
to track the fact that pragma: keep cannot be used to keep multiple includes of 
the same file?

I blindly rejected the possibility of recognizing this construction (known as 
X-Macros: [1]), but maybe it can be done...

Do you have any ideas for how to detect it? One thing that comes to mind is a 
rule that says;

  If included.h uses a symbol defined in includer.x, before the line that
  #includes includer.h, keep the include line. And then something about it
  not being #undef:ed in between.

It's sort of the reverse of what IWYU is already doing.

I guess it's not limited to the preprocessor, either. It could be something 
like;

 // translation_unit.cc
 template<class T>
 struct Foo { };

 #include "foo_specializations.h"

 // foo_specializations.h
 template<> struct Foo<int> { static bool available = true; };
 template<> struct Foo<char> { static bool available = true; };
 template<> struct Foo<const char*> { static bool available = true; };

But if it's possible to cross-reference an included file with the file that 
includes it, this might be doable.

[1] http://www.ddj.com/cpp/184401387

Original comment by kim.gras...@gmail.com on 13 Jul 2012 at 6:56

GoogleCodeExporter commented 9 years ago
I just noticed this is a duplicate of issue #45, which has some further 
information.

Original comment by kim.gras...@gmail.com on 15 Jul 2012 at 11:44

GoogleCodeExporter commented 9 years ago
If anyone wants to close this as a duplicate, though, please update the summary 
of issue #45, because it's not descriptive at all.

Original comment by a...@aryeh.name on 19 Jul 2012 at 7:36