Problem in SLocEntry creation

$ cat file.c
#define WINDOW win
#include "file.h"
$ cat file.h
#define P_(args) args
extern void f P_((WINDOW win));
$ clang -c file.c
error: unknown type name 'win'
./file.h:1:18: note: expanded from macro 'P_'
#define P_(args) args
                        ^
1 error generated.

It seems that when the spelling location for 'win' is computed we end up
into an expansion SLocEntry despite we start from a file SLocEntry.

This is the dump of relevant SLocEntry:

4: file 12275-12329 name:./file.h iloc:30
5: macro 2147495978-2147495982 exp:12311-12326 sloc:12292 text:args
6: macro 2147495983-2147495986 exp:12315-12315 sloc:17 text:win
7: arg 2147495987-2147496011 exp:2147495978-2147495978 sloc:12314
text:(WINDOW win));

The location for 'win' is 2147496008, i.e. fid 7 and offset 21, if we
sum that offset to base spelling loc 12314 + 21 = 12335, but this offset
belong to fid 6 that is not a file SLocEntry.

So we get as spelling loc a file loc that is erroneously inside an
expansion SLocEntry, this produces the effect to obtain an invalid loc
that confuse diagnostics, so that, as you can see above, no
file:line:column is shown before "error:".

Do you know what might be the reason for that and/or what is the correct
remediation?

I'm seeing (with a binary patched to be more informative):

FileID 1: file file.c included at 0@0 "#define WINDOW win\n#include
\"file.h\"\n"
FileID 2: file (null) included at 0@0 "# 1 \"<built-in>\" 3\n#define
__llvm__ 1\n#d ..."
FileID 3: file ./file.h included at 1@28 "#define P_(args)
args\nextern void ..."
FileID 4: macro expansion 3@43 - 3@58, spelling 3@24 "args\nextern
void f _P((WINDOW win));"
FileID 5: macro expansion 3@47 - 3@47, spelling 1@15 "win\n#include \"file.h\""
FileID 6: macro arg expansion 4@0 - 4@0, spelling 3@46 "(WINDOW win));"
FileID 7: macro arg expansion 4@0 - 4@0, spelling 3@54 "win));"

... which is Not Right. We should also have a macro arg expansion 4@0
- 4@0 for the 'WINDOW' expansion inside the 'P_' expansion, whose
spelling location should point at FileID 5@0, and that should be the
location which the diagnostic points at.

The diagnostic we're currently producing is:

6@21: error: unknown type name 'win'
3@24: note: expanded from macro 'P_'
#define P_(args) args
                        ^

... which is nonsense: FileID 6 is only 1 character long. Things then
rapidly go downhill. This results in getFileLoc mapping from 6@21 to
3@46+21 == 3@67, which again is nonsense: FileID 3 is only 61
characters long. This gives us a SourceLocation with isFileID() true,
but which points at 5@0.

$ cat file.c
#define WINDOW win
#include "file.h"
$ cat file.h
#define P_(args) args
extern void f P_((WINDOW win));
$ clang -c file.c
error: unknown type name 'win'
./file.h:1:18: note: expanded from macro 'P_'
#define P_(args) args
                       ^
1 error generated.

It seems that when the spelling location for 'win' is computed we end up
into an expansion SLocEntry despite we start from a file SLocEntry.

This is the dump of relevant SLocEntry:

4: file 12275-12329 name:./file.h iloc:30
5: macro 2147495978-2147495982 exp:12311-12326 sloc:12292 text:args
6: macro 2147495983-2147495986 exp:12315-12315 sloc:17 text:win
7: arg 2147495987-2147496011 exp:2147495978-2147495978 sloc:12314
text:(WINDOW win));

The location for 'win' is 2147496008, i.e. fid 7 and offset 21, if we
sum that offset to base spelling loc 12314 + 21 = 12335, but this offset
belong to fid 6 that is not a file SLocEntry.

So we get as spelling loc a file loc that is erroneously inside an
expansion SLocEntry, this produces the effect to obtain an invalid loc
that confuse diagnostics, so that, as you can see above, no
file:line:column is shown before "error:".

Do you know what might be the reason for that and/or what is the correct
remediation?

This was due to "merging" macro argument tokens into one SLocEntry chunk, a token from a file should not be combined with one from an expansion.

Thanks for the test case! Fixed in r170616.