<table border="1" cellspacing="0" cellpadding="8">
    <tr>
        <th>Issue</th>
        <td>
            <a href=https://github.com/llvm/llvm-project/issues/59392>59392</a>
        </td>
    </tr>

    <tr>
        <th>Summary</th>
        <td>
            Support finding headers for target symbol decl from a macro
        </td>
    </tr>

    <tr>
      <th>Labels</th>
      <td>
            clang-include-cleaner
      </td>
    </tr>

    <tr>
      <th>Assignees</th>
      <td>
      </td>
    </tr>

    <tr>
      <th>Reporter</th>
      <td>
          hokein
      </td>
    </tr>
</table>

<pre>
    This addresses the FIXME in [FindHeaders.cpp](https://github.com/llvm/llvm-project/blob/main/clang-tools-extra/include-cleaner/lib/FindHeaders.cpp#L21).

Based on the offline discussion, the idea is to follow the *expansion* location -- the corresponding header for the target symbol is the file that expands the decl's name location (rationale: the expansion location brings the symbol)

Cases we considered:
1) the target decl is argument-expanded from a macro in main file/other headers
2) the target decl is body-expanded from a macro in main file
3) the target decl is body-expanded from a macro in other headers
4) the target decl is token-pasted

For cases 1) and 2), spelling loc might be a better choice, but in general both spelling and expansion location will point to the same file. An examples

```
// declare.h
#include "macro.h"
DEFINE_CLASS(Foo);

// macro.h
#define DEFINE_CLASS(name) class name {};

// main.cpp
#include "declare.h"
^Foo a; // For the annotated reference, the corresponding header of the target symbol `Foo` is the `declare.h` 
```

For case 3), see the following example:

```
// declare.h
#include "macros.h"
DEFINE_Foo

// macros.h
#define DEFINE_Foo class Foo {};

// main.cpp
#include "declare.h"
void test(^Foo foo);  //  declare.h is the header brings the class Foo (which indicates the expansion location), though it is spelled in a macro body in another file.
```

For case 4), a typical example is:

```
// declare.h
#include "flags.h"
DECLARE_FLAGS(foo);

// flags.h
#define DECLARE_FLAGS(name) extern int FLAG_##name;

// main.cc
#include "declare.h"

void foo() {
   $1^FLAG_foo; // we should include declare.h, => expansion location
}
```
</pre>
<img width="1px" height="1px" alt="" src="http://email.email.llvm.org/o/eJysVk1v4zYQ_TX0ZWBDpj5iH3Twl9oF0h66PfQWUORIYpcmBZLaJP--ICWtncRJU2yBILZF8s3jvHmjYc7JViOWJN-T_Lhgg--MLTvzDaVe1EY8l3920gETwqJz6MB3CNWXv347gdRA8n0ltfgVmUDrVrzvSX4kdNN53zuS7gitCK1a6buhXnFzJrRS6vv8seyt-Ru5J7SqlakJrc5MakIrrphul94Y5Zb45C0jtJKaq0HgkitkGm2AkOHI6_g0vadrQrcrkhxJshv_75lDAUZH9qZplNQIQjo-OCeNJvQQV6RABtKBN9AYpcxjfEroDp96psedO1CGMy-NhuUyrnNjLbreaCF1C13kAo2xcdEz26IH93yujYrYHUIjFYLvmIcILManArki9M6BZme8RCF0Y-M3ppCku7j1B5_LttpK3Y5AYzBCt9cpOLCg3mOgq50UaFEEgeJayNc128jkQMkuCdLbdjij9suRKwporDkDgzPj1oQqCKrFOxFaGd-hnZLgRnT6EXoosc8gR6T0BhL8K8gNStk7QN58Q73smfMorpNXGQs8JjCmimkB4VahblyPSgXhleFwlm3noUZgUKP3aIF3RnIMG-vBBzYtarRMQW18dzkcEG-I-iiVgt5I7UNNRm1DbYSMrGCnAZ_YuVforrmSIpn-xp_RgvGGzOKqm5-mk6GAUBpTteoIpePq8VR9-f30cLjfff1K6KYyJlw23b8IM-LOR2dUgU3w1iuEUNEhcVwxN9U3uduTu-N7oFJHM9_gernIzJbkp8oYYCTdwwRQTe5jWhvPPAqw2KBFPUrxrmtNc8O0pEhCBopkti8pkguLIoHbeX9ROJDO5YI4toDYX0LoScMfZvw5Fd1bGQP5d4Rz7yoXMjqqFb79f2J9N1KAR-cJ3UzCNXN5wSzf5Z5zyid9rprcFTm6eewk70BqITnz00vqrZ0mCXxnhrYD6QN4dCCK4My5ZYRuEn_rsXNEt31G42wKwMA_95IzNWsL0v28vI1i7Ut1D_e7P04P1f3ul-Cx5gOXzmffaP0SYrYpPnm0GkLbCUsPhKaEpnH1gxLgn7TrpQ4i5U2IGAosPodQBNk6lEaIHHZcbP2I4DozqCDXGOEK_gAkPZL0dEv4MfDd8VXyF6JMxTbdsgWW6-Iuyba02GSLrqR13uQ8y-sN52mdZgyTpFjXzXqDaY6YLmRJE0rXNNkk2yzLslWW8yLLiqLIUKRpviVZgmcm1SoMOitj24V0bsAy36ZbulCsRuXi0EXpOO28mW9omMdsGQelemgdyRIlnXcXRC-9wvLr0PfGemjkdStz4wTyopHFt9z123ExWFX-51ktXsQRWsW7_BMAAP__sXUroQ">