<div dir="ltr"><div class="gmail_extra"><div class="gmail_quote">On Mon, Aug 17, 2015 at 9:24 AM, Nico Weber <span dir="ltr"><<a href="mailto:thakis@chromium.org" target="_blank">thakis@chromium.org</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">thakis added a subscriber: thakis.<br>
<div><div class="h5"><br>
================<br>
Comment at: lib/Driver/Tools.cpp:398<br>
@@ +397,3 @@<br>
+              FoundPTH = !UsePCH;<br>
+            }<br>
+          }<br>
----------------<br>
kimgr wrote:<br>
> kimgr wrote:<br>
> > kimgr wrote:<br>
> > > kimgr wrote:<br>
> > > > Add a `break;` here so we don't continue searching after a valid path has been found<br>
> > > The GCC docs here [1] say:<br>
> > ><br>
> > >     If not found there, it is searched for in the remainder of the #include "..." search chain as normal.<br>
> > ><br>
> > > I can't tell if the quotes are significant and if they mean only -I is searched. I don't have a GCC environment currently to test with.<br>
> > ><br>
> > > [1] <a href="https://gcc.gnu.org/onlinedocs/gcc-4.9.3/gcc/Preprocessor-Options.html#index-nostdinc_002b_002b-1026" rel="noreferrer" target="_blank">https://gcc.gnu.org/onlinedocs/gcc-4.9.3/gcc/Preprocessor-Options.html#index-nostdinc_002b_002b-1026</a><br>
> > I found a FreeBSD machine and set up GCC. I had to adjust the repro case to use `truss` instead of `strace`, so I hope I didn't mess anything up.<br>
> ><br>
> > I removed the rule generating the .gch file, so GCC would have to keep searching and it appears to be following the entire include search path, including system paths. Trace below:<br>
> ><br>
> > ...<br>
> > 30860: stat("./precompiled.header.gch",0x7fffffffe540) ERR#2 'No such file or directory'<br>
> > 30860: open("./precompiled.header",O_NOCTTY,0666) ERR#2 'No such file or directory'<br>
> > 30860: stat("./build/include/precompiled.header.gch",0x7fffffffe540) ERR#2 'No such file or directory'<br>
> > 30860: open("./build/include/precompiled.header",O_NOCTTY,0666) ERR#2 'No such file or directory'<br>
> > 30860: stat("./include/precompiled.header.gch",0x7fffffffe540) ERR#2 'No such file or directory'<br>
> > 30860: open("./include/precompiled.header",O_NOCTTY,0666) ERR#2 'No such file or directory'<br>
> > 30860: lstat("/usr",{ mode=drwxr-xr-x ,inode=9,size=16,blksize=4096 }) = 0 (0x0)<br>
> > 30860: lstat("/usr/local",{ mode=drwxr-xr-x ,inode=115,size=16,blksize=4096 }) = 0 (0x0)<br>
> > 30860: lstat("/usr/local/lib",{ mode=drwxr-xr-x ,inode=16476,size=1318,blksize=84480 }) = 0 (0x0)<br>
> > 30860: lstat("/usr/local/lib/gcc48",{ mode=drwxr-xr-x ,inode=24335,size=66,blksize=131072 }) = 0 (0x0)<br>
> > 30860: lstat("/usr/local/lib/gcc48/include",{ mode=drwxr-xr-x ,inode=24336,size=3,blksize=131072 }) = 0 (0x0)<br>
> > 30860: lstat("/usr/local/lib/gcc48/include/c++",{ mode=drwxr-xr-x ,inode=24337,size=98,blksize=131072 }) = 0 (0x0)<br>
> > 30860: lstat("/usr/local/lib/gcc48/include/c++/precompiled.header",0x7fffffffd3d8) ERR#2 'No such file or directory'<br>
> > 30860: stat("/usr/local/lib/gcc48/include/c++/precompiled.header.gch",0x7fffffffe540) ERR#2 'No such file or directory'<br>
> > 30860: open("/usr/local/lib/gcc48/include/c++/precompiled.header",O_NOCTTY,0666) ERR#2 'No such file or directory'<br>
> > 30860: lstat("/usr",{ mode=drwxr-xr-x ,inode=9,size=16,blksize=4096 }) = 0 (0x0)<br>
> > 30860: lstat("/usr/local",{ mode=drwxr-xr-x ,inode=115,size=16,blksize=4096 }) = 0 (0x0)<br>
> > 30860: lstat("/usr/local/lib",{ mode=drwxr-xr-x ,inode=16476,size=1318,blksize=84480 }) = 0 (0x0)<br>
> > 30860: lstat("/usr/local/lib/gcc48",{ mode=drwxr-xr-x ,inode=24335,size=66,blksize=131072 }) = 0 (0x0)<br>
> > 30860: lstat("/usr/local/lib/gcc48/include",{ mode=drwxr-xr-x ,inode=24336,size=3,blksize=131072 }) = 0 (0x0)<br>
> > 30860: lstat("/usr/local/lib/gcc48/include/c++",{ mode=drwxr-xr-x ,inode=24337,size=98,blksize=131072 }) = 0 (0x0)<br>
> > 30860: lstat("/usr/local/lib/gcc48/include/c++/x86_64-portbld-freebsd10.1",{ mode=drwxr-xr-x ,inode=21305,size=4,blksize=131072 }) = 0 (0x0)<br>
> > 30860: lstat("/usr/local/lib/gcc48/include/c++/x86_64-portbld-freebsd10.1/precompiled.header",0x7fffffffd3d8) ERR#2 'No such file or directory'<br>
> > 30860: stat("/usr/local/lib/gcc48/include/c++//x86_64-portbld-freebsd10.1/precompiled.header.gch",0x7fffffffe540) ERR#2 'No such file or directory'<br>
> > 30860: open("/usr/local/lib/gcc48/include/c++//x86_64-portbld-freebsd10.1/precompiled.header",O_NOCTTY,0666) ERR#2 'No such file or directory'<br>
> > 30860: lstat("/usr",{ mode=drwxr-xr-x ,inode=9,size=16,blksize=4096 }) = 0 (0x0)<br>
> > 30860: lstat("/usr/local",{ mode=drwxr-xr-x ,inode=115,size=16,blksize=4096 }) = 0 (0x0)<br>
> > 30860: lstat("/usr/local/lib",{ mode=drwxr-xr-x ,inode=16476,size=1318,blksize=84480 }) = 0 (0x0)<br>
> > 30860: lstat("/usr/local/lib/gcc48",{ mode=drwxr-xr-x ,inode=24335,size=66,blksize=131072 }) = 0 (0x0)<br>
> > 30860: lstat("/usr/local/lib/gcc48/include",{ mode=drwxr-xr-x ,inode=24336,size=3,blksize=131072 }) = 0 (0x0)<br>
> > 30860: lstat("/usr/local/lib/gcc48/include/c++",{ mode=drwxr-xr-x ,inode=24337,size=98,blksize=131072 }) = 0 (0x0)<br>
> > 30860: lstat("/usr/local/lib/gcc48/include/c++/backward",{ mode=drwxr-xr-x ,inode=21290,size=10,blksize=131072 }) = 0 (0x0)<br>
> > 30860: lstat("/usr/local/lib/gcc48/include/c++/backward/precompiled.header",0x7fffffffd3d8) ERR#2 'No such file or directory'<br>
> > 30860: stat("/usr/local/lib/gcc48/include/c++//backward/precompiled.header.gch",0x7fffffffe540) ERR#2 'No such file or directory'<br>
> > 30860: open("/usr/local/lib/gcc48/include/c++//backward/precompiled.header",O_NOCTTY,0666) ERR#2 'No such file or directory'<br>
> > 30860: lstat("/usr",{ mode=drwxr-xr-x ,inode=9,size=16,blksize=4096 }) = 0 (0x0)<br>
> > 30860: lstat("/usr/local",{ mode=drwxr-xr-x ,inode=115,size=16,blksize=4096 }) = 0 (0x0)<br>
> > 30860: lstat("/usr/local/lib",{ mode=drwxr-xr-x ,inode=16476,size=1318,blksize=84480 }) = 0 (0x0)<br>
> > 30860: lstat("/usr/local/lib/gcc48",{ mode=drwxr-xr-x ,inode=24335,size=66,blksize=131072 }) = 0 (0x0)<br>
> > 30860: lstat("/usr/local/lib/gcc48/gcc",{ mode=drwxr-xr-x ,inode=145103,size=3,blksize=131072 }) = 0 (0x0)<br>
> > 30860: lstat("/usr/local/lib/gcc48/gcc/x86_64-portbld-freebsd10.1",{ mode=drwxr-xr-x ,inode=145104,size=3,blksize=131072 }) = 0 (0x0)<br>
> > 30860: lstat("/usr/local/lib/gcc48/gcc/x86_64-portbld-freebsd10.1/4.8.4",{ mode=drwxr-xr-x ,inode=145105,size=16,blksize=131072 }) = 0 (0x0)<br>
> > 30860: lstat("/usr/local/lib/gcc48/gcc/x86_64-portbld-freebsd10.1/4.8.4/include",{ mode=drwxr-xr-x ,inode=145106,size=64,blksize=131072 }) = 0 (0x0)<br>
> > 30860: lstat("/usr/local/lib/gcc48/gcc/x86_64-portbld-freebsd10.1/4.8.4/include/precompiled.header",0x7fffffffd3d8) ERR#2 'No such file or directory'<br>
> > 30860: stat("/usr/local/lib/gcc48/gcc/x86_64-portbld-freebsd10.1/4.8.4/include/precompiled.header.gch",0x7fffffffe540) ERR#2 'No such file or directory'<br>
> > 30860: open("/usr/local/lib/gcc48/gcc/x86_64-portbld-freebsd10.1/4.8.4/include/precompiled.header",O_NOCTTY,0666) ERR#2 'No such file or directory'<br>
> > 30860: lstat("/usr",{ mode=drwxr-xr-x ,inode=9,size=16,blksize=4096 }) = 0 (0x0)<br>
> > 30860: lstat("/usr/local",{ mode=drwxr-xr-x ,inode=115,size=16,blksize=4096 }) = 0 (0x0)<br>
> > 30860: lstat("/usr/local/include",{ mode=drwxr-xr-x ,inode=16474,size=218,blksize=14336 }) = 0 (0x0)<br>
> > 30860: lstat("/usr/local/include/precompiled.header",0x7fffffffd3d8) ERR#2 'No such file or directory'<br>
> > 30860: stat("/usr/local/include/precompiled.header.gch",0x7fffffffe540) ERR#2 'No such file or directory'<br>
> > 30860: open("/usr/local/include/precompiled.header",O_NOCTTY,0666) ERR#2 'No such file or directory'<br>
> > 30860: lstat("/usr",{ mode=drwxr-xr-x ,inode=9,size=16,blksize=4096 }) = 0 (0x0)<br>
> > 30860: lstat("/usr/local",{ mode=drwxr-xr-x ,inode=115,size=16,blksize=4096 }) = 0 (0x0)<br>
> > 30860: lstat("/usr/local/lib",{ mode=drwxr-xr-x ,inode=16476,size=1318,blksize=84480 }) = 0 (0x0)<br>
> > 30860: lstat("/usr/local/lib/gcc48",{ mode=drwxr-xr-x ,inode=24335,size=66,blksize=131072 }) = 0 (0x0)<br>
> > 30860: lstat("/usr/local/lib/gcc48/gcc",{ mode=drwxr-xr-x ,inode=145103,size=3,blksize=131072 }) = 0 (0x0)<br>
> > 30860: lstat("/usr/local/lib/gcc48/gcc/x86_64-portbld-freebsd10.1",{ mode=drwxr-xr-x ,inode=145104,size=3,blksize=131072 }) = 0 (0x0)<br>
> > 30860: lstat("/usr/local/lib/gcc48/gcc/x86_64-portbld-freebsd10.1/4.8.4",{ mode=drwxr-xr-x ,inode=145105,size=16,blksize=131072 }) = 0 (0x0)<br>
> > 30860: lstat("/usr/local/lib/gcc48/gcc/x86_64-portbld-freebsd10.1/4.8.4/include-fixed",{ mode=drwxr-xr-x ,inode=145194,size=12,blksize=131072 }) = 0 (0x0)<br>
> > 30860: lstat("/usr/local/lib/gcc48/gcc/x86_64-portbld-freebsd10.1/4.8.4/include-fixed/precompiled.header",0x7fffffffd3d8) ERR#2 'No such file or directory'<br>
> > 30860: stat("/usr/local/lib/gcc48/gcc/x86_64-portbld-freebsd10.1/4.8.4/include-fixed/precompiled.header.gch",0x7fffffffe540) ERR#2 'No such file or directory'<br>
> > 30860: open("/usr/local/lib/gcc48/gcc/x86_64-portbld-freebsd10.1/4.8.4/include-fixed/precompiled.header",O_NOCTTY,0666) ERR#2 'No such file or directory'<br>
> > 30860: lstat("/usr",{ mode=drwxr-xr-x ,inode=9,size=16,blksize=4096 }) = 0 (0x0)<br>
> > 30860: lstat("/usr/include",{ mode=drwxr-xr-x ,inode=111,size=307,blksize=19968 }) = 0 (0x0)<br>
> > 30860: lstat("/usr/include/precompiled.header",0x7fffffffd3d8) ERR#2 'No such file or directory'<br>
> > 30860: stat("/usr/include/precompiled.header.gch",0x7fffffffe540) ERR#2 'No such file or directory'<br>
> > 30860: open("/usr/include/precompiled.header",O_NOCTTY,0666) ERR#2 'No such file or directory'<br>
> > 30860: stat("/usr/share/nls/C/<a href="http://libc.cat" rel="noreferrer" target="_blank">libc.cat</a>",0x7fffffffdf18) ERR#2 'No such file or directory'<br>
> > 30860: stat("/usr/share/nls/libc/C",0x7fffffffdf18) ERR#2 'No such file or directory'<br>
> > 30860: stat("/usr/local/share/nls/C/<a href="http://libc.cat" rel="noreferrer" target="_blank">libc.cat</a>",0x7fffffffdf18) ERR#2 'No such file or directory'<br>
> > 30860: stat("/usr/local/share/nls/libc/C",0x7fffffffdf18) ERR#2 'No such file or directory'<br>
> > 30860: write(2,"cc1plus: fatal error: precompile"...,68) = 68 (0x44)<br>
> > 30860: write(2,"compilation terminated.\n",24)       = 24 (0x18)<br>
> > ...<br>
> ><br>
> So it seems that GCC *does* scan the entire header search path. Unfortunately, that information doesn't seem to be available to the driver (looks to be set up in CompilerInstance::createPreprocessor.<br>
><br>
> Should this logic for PCH/PTH scanning move out of the driver and into the frontend?<br>
</div></div>gcc also checks if the gch file is a directory and if so finds the first file with matching language / defines etc. It also uses gch files for #included files instead of just -included files (<a href="https://gcc.gnu.org/onlinedocs/gcc/Precompiled-Headers.html" rel="noreferrer" target="_blank">https://gcc.gnu.org/onlinedocs/gcc/Precompiled-Headers.html</a>). I thought clang intentionally did none of this so it doesn't have to stat all these directories.</blockquote><div><br></div><div>Right, so the question is: what do we want our semantics to be here? Do we have sufficient motivation to change our existing design to something closer to GCC's? Or should we be encouraging people to use modules instead of PCH here, which has all of the desirable properties of the above, and doesn't have the "no preceding tokens" limitation?</div></div></div></div>