[clang] [ASTWriter] Detect more non-affecting FileIDs to reduce source location duplication (PR #112015)

Jan Svoboda via cfe-commits cfe-commits at lists.llvm.org
Tue Oct 15 14:45:23 PDT 2024


jansvoboda11 wrote:

I was looking at the affecting module map logic for a reason unrelated to yours, but ended up needing something similar to what you're trying to achieve. Here's an example:

```
//--- X1.modulemap
module X1 { header "X1.h" }
//--- X2.modulemap
module X2 { header "X2.h" }
//--- A.modulemap
module A { header "A.h" }
//--- B.modulemap
module B { header "B.h" }
//--- X1.h
#include "A.h"
#include "B.h"
//--- X2.h
#include "B.h"
#include "A.h"
//--- A.h
#include "B.h"
//--- B.h
```

Intuitively, I would expect the set of affecting files between modules X1 and X2 to be the same (at least when it comes to files related to modules A and B).

Assuming implicit module maps, the problem is as follows:

* In module X1:
  * The first include in X1.h reads A.modulemap and creates local SLocEntry.
  * A.pcm is loaded and `Module::DefinitionLoc` is re-associated with the loaded SLocEntry for A.modulemap.
  * The second include in X2.h reads B.modulemap and creates local SLocEntry.
  * B.pcm is loaded and `Module::DefinitionLoc` is re-associated with the loaded SLocEntry for B.modulemap.
  * When computing the set of affecting input files, we start out assuming all files tied to local SLocEntries are affecting, so both A.modulemap and B.modulemap are candidates at the start.
  * Then we say only module map files that are not in the set derived from `Module::DefinitionLoc` are non-affecting.
  * Both A.modulemap and B.modulemap are in the set, so both end up being affecting.

* In module X2:
  * The first include in X2.h reads B.modulemap and creates local SLocEntry.
  * B.pcm is loaded and `Module::DefinitionLoc` is re-associated with the loaded SLocEntry for B.modulemap.
  * A.pcm is transitively loaded and `ModuleDefinitionLoc` is associated with the loaded SLocEntry for A.modulemap.
  * The second include in X2.h doesn't read any module map file, since all necessary information is known thanks to A.pcm.
  * When computing the set of affecting input files, the initial set only contains B.modulemap (because it's associated with the local SLocEntry), but not A.modulemap (because it's only associated with the loaded SLocEntry).
  * B.modulemap is in the set derived from `Module::DefinitionLoc` so it ends up being affecting.

This is unexpected and I think it breaks the correctness of clang-scan-deps. I think we might need to take your patch a bit further and make it so that `ASTWriter::WriteInputFiles()` doesn't care whether the SLocEntry associated with the file through `Module::DefinitionLoc` is loaded or local.

https://github.com/llvm/llvm-project/pull/112015


More information about the cfe-commits mailing list