Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Closed
vsapsai opened this issue Jun 15, 2015 · 6 comments
Closed

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

vsapsai opened this issue Jun 15, 2015 · 6 comments

Comments

@vsapsai
Copy link
Contributor

vsapsai commented Jun 15, 2015

Originally reported on Google Code with ID 74

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/nsEditPropertyAtomList.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.html#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>.
 :)

Reported by ayg@aryeh.name on 2012-07-11 11:27:16

@vsapsai
Copy link
Contributor Author

vsapsai commented Jun 15, 2015

> 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.

Reported by kim.grasman on 2012-07-13 17:44:51

@vsapsai
Copy link
Contributor Author

vsapsai commented Jun 15, 2015

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.

Reported by vsapsai on 2012-07-13 18:39:46

@vsapsai
Copy link
Contributor Author

vsapsai commented Jun 15, 2015

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

Reported by kim.grasman on 2012-07-13 18:56:22

@vsapsai
Copy link
Contributor Author

vsapsai commented Jun 15, 2015

I just noticed this is a duplicate of issue #45, which has some further information.

Reported by kim.grasman on 2012-07-15 11:44:03

@vsapsai
Copy link
Contributor Author

vsapsai commented Jun 15, 2015

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

Reported by ayg@aryeh.name on 2012-07-19 07:36:47

@kimgr
Copy link
Contributor

kimgr commented Apr 9, 2017

Possible duplicate of #45 and #109. Can't reproduce with a smaller example. Closing.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants