berkus / include-what-you-use

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

Export pragma does not work if <> is used #121

Open GoogleCodeExporter opened 9 years ago

GoogleCodeExporter commented 9 years ago
Export pragma only works when the include uses "" to include the filename but 
not if <> is used.

in the tarball tst.c uses "" and tst2.c uses <>

running IWYU on these files gives:
frans@2600-m4:/home/home/frans/clang/FMtst$ include-what-you-use -I. tst.c

(tst.c has correct #includes/fwd-decls)
frans@2600-m4:/home/home/frans/clang/FMtst$ include-what-you-use -I. tst2.c

tst2.c should add these lines:
#include <stdio.h>                      // for printf

tst2.c should remove these lines:

The full include-list for tst2.c:
#include <a.h>                          // for HELLO
#include <stdio.h>                      // for printf

---

I expected the output of tst and tst2 to be identical.

This is on ubuntu 12.04 (precise) with teh svn head of feb 8, 2014

Original issue reported on code.google.com by fransmeu...@gmail.com on 9 Feb 2014 at 11:55

Attachments:

GoogleCodeExporter commented 9 years ago
Thanks for the report.

This is a long-standing difficulty where IWYU is very particular about angled 
vs. quoted includes. It will probably take some archaeology to figure out 
exactly why, but I can at least explain the reasoning as it is:

- Mappings in IWYU are created between two quoted includes, so <stdio.h> is 
mapped to <cstdio>, for example.
- When IWYU finds the export pragma, it adds a mapping dynamically from 
<stdio.h> to a.h.
- The exact quoting of a.h is determined by finding it on the header search 
path:
  1) If the search path entry is a user path (-I), it assumes quotes: "a.h"
  2) If the search path entry is a system path (-isystem), it assumes angles: <a.h>
- Then, when IWYU does its analysis, there's a step where it matches the actual 
#include in tst2.c to the mapping table. Since the spelling in tst2.c is <a.h> 
and the mapping spelling is "a.h", it doesn't match.

To force the behavior you want, you can pass "-isystem ." on the command-line, 
but that might have other adverse effects, since all local headers will now be 
found in the system path.

I'm not sure if IWYU is overly strict about system vs. user paths, but I 
suspect it is. There's been some discussion on other issues (e.g. #5, comment 
41) that maybe we should only ever move or remove #includes, never synthesize 
new ones. I believe that would solve this problem as well, but I'm guessing at 
this point.

Original comment by kim.gras...@gmail.com on 9 Feb 2014 at 4:07

GoogleCodeExporter commented 9 years ago
Assuming " " on -I does not seem right to me. I'm into C, not C++. 
if a filename is in < > it is searched for using the dirs in -I then the system 
dirs.
If the filename is in " " it is searched for in the current dir, then as if it 
was using < >
So from a performance point of view it makes sense to use < > for dirs that are 
not in the current dir (it saves a lookup).

I'll check out on -isystem

Original comment by fransmeu...@gmail.com on 10 Feb 2014 at 2:50

GoogleCodeExporter commented 9 years ago
I tried replacing -I with -isystem . but that did not make a difference

Original comment by fransmeu...@gmail.com on 12 Feb 2014 at 8:47

GoogleCodeExporter commented 9 years ago
Oops, right you are. I was sure I'd tried it, but apparently not.

I don't think there are any significant differences between C and C++ regarding 
<> vs "", it's still the same preprocessor AFAIK.

It could be that the condition to select between "" and <> should be (just as 
you say) only whether the header is adjacent to the including file or not.

I'm not in a position to experiment with this right now, but if you want to 
help out you can start in iwyu_path_util.cc, ConvertToQuotedInclude, and see if 
all callers can be made to pass in context representing the "current" dir (i.e. 
includee's dirname).

Original comment by kim.gras...@gmail.com on 13 Feb 2014 at 6:42