169 lines · c
1// This test checks that pruning of header search paths produces consistent dependency graphs.2//3// When pruning header search paths for a module, we can't remove any paths its dependencies use.4// Otherwise, we could get either of the following dependency graphs depending on the search path5// configuration of the particular TU that first discovered the module:6// X:<hash1> -> Y:<hash2>7// X:<hash1> -> Y:<hash3>8// We can't have the same version of module X depend on multiple different versions of Y based on9// the TU configuration.10//11// Keeping all header search paths (transitive) dependencies use will ensure we get consistent12// dependency graphs:13// X:<hash1> -> Y:<hash2>14// X:<hash4> -> Y:<hash3>15 16// RUN: rm -rf %t && mkdir %t17// RUN: split-file %s %t18 19//--- a/a.h20//--- b/b.h21//--- begin/begin.h22//--- end/end.h23//--- Y.h24#include "begin.h"25#if __has_include("a.h")26#include "a.h"27#endif28#include "end.h"29 30//--- X.h31#include "Y.h"32 33//--- module.modulemap34module Y { header "Y.h" }35module X { header "X.h" }36 37//--- test.c38#include "X.h"39 40//--- cdb_with_a.json.template41[{42 "file": "DIR/test.c",43 "directory": "DIR",44 "command": "clang -fsyntax-only test.c -fmodules -fimplicit-modules -fmodules-cache-path=DIR/module-cache -fimplicit-module-maps -Ibegin -Ia -Ib -Iend"45}]46 47//--- cdb_without_a.json.template48[{49 "file": "DIR/test.c",50 "directory": "DIR",51 "command": "clang -fsyntax-only test.c -fmodules -fimplicit-modules -fmodules-cache-path=DIR/module-cache -fimplicit-module-maps -Ibegin -Ib -Iend"52}]53 54// RUN: sed -e "s|DIR|%/t|g" %t/cdb_with_a.json.template > %t/cdb_with_a.json55// RUN: sed -e "s|DIR|%/t|g" %t/cdb_without_a.json.template > %t/cdb_without_a.json56 57// RUN: clang-scan-deps -compilation-database %t/cdb_with_a.json -format experimental-full -optimize-args=header-search > %t/results.json58// RUN: clang-scan-deps -compilation-database %t/cdb_without_a.json -format experimental-full -optimize-args=header-search >> %t/results.json59// RUN: cat %t/results.json | sed 's:\\\\\?:/:g' | FileCheck %s -DPREFIX=%/t60 61// CHECK: {62// CHECK-NEXT: "modules": [63// CHECK-NEXT: {64// CHECK-NEXT: "clang-module-deps": [65// CHECK-NEXT: {66// CHECK-NEXT: "context-hash": "[[HASH_Y_WITH_A:.*]]",67// CHECK-NEXT: "module-name": "Y"68// CHECK-NEXT: }69// CHECK-NEXT: ],70// CHECK-NEXT: "clang-modulemap-file": "[[PREFIX]]/module.modulemap",71// CHECK-NEXT: "command-line": [72// CHECK: ],73// CHECK-NEXT: "context-hash": "[[HASH_X:.*]]",74// CHECK-NEXT: "file-deps": [75// CHECK-NEXT: "[[PREFIX]]/module.modulemap",76// CHECK-NEXT: "[[PREFIX]]/X.h"77// CHECK-NEXT: ],78// CHECK-NEXT: "link-libraries": [],79// CHECK-NEXT: "name": "X"80// CHECK-NEXT: },81// CHECK-NEXT: {82// CHECK-NEXT: "clang-module-deps": [],83// CHECK-NEXT: "clang-modulemap-file": "[[PREFIX]]/module.modulemap",84// CHECK-NEXT: "command-line": [85// CHECK: ],86// CHECK-NEXT: "context-hash": "[[HASH_Y_WITH_A]]",87// CHECK-NEXT: "file-deps": [88// CHECK-NEXT: "[[PREFIX]]/module.modulemap",89// CHECK-NEXT: "[[PREFIX]]/Y.h",90// CHECK-NEXT: "[[PREFIX]]/begin/begin.h",91// CHECK-NEXT: "[[PREFIX]]/a/a.h",92// CHECK-NEXT: "[[PREFIX]]/end/end.h"93// CHECK-NEXT: ],94// CHECK-NEXT: "link-libraries": [],95// CHECK-NEXT: "name": "Y"96// CHECK-NEXT: }97// CHECK-NEXT: ],98// CHECK-NEXT: "translation-units": [99// CHECK-NEXT: {100// CHECK: "clang-context-hash": "{{.*}}",101// CHECK-NEXT: "clang-module-deps": [102// CHECK-NEXT: {103// CHECK-NEXT: "context-hash": "[[HASH_X]]",104// CHECK-NEXT: "module-name": "X"105// CHECK-NEXT: }106// CHECK-NEXT: ],107// CHECK-NEXT: "command-line": [108// CHECK: ],109// CHECK: "file-deps": [110// CHECK-NEXT: "[[PREFIX]]/test.c"111// CHECK-NEXT: ],112// CHECK-NEXT: "input-file": "[[PREFIX]]/test.c"113// CHECK-NEXT: }114 115// CHECK: {116// CHECK-NEXT: "modules": [117// CHECK-NEXT: {118// CHECK-NEXT: "clang-module-deps": [119// CHECK-NEXT: {120// CHECK-NEXT: "context-hash": "[[HASH_Y_WITHOUT_A:.*]]",121// CHECK-NEXT: "module-name": "Y"122// CHECK-NEXT: }123// CHECK-NEXT: ],124// CHECK-NEXT: "clang-modulemap-file": "[[PREFIX]]/module.modulemap",125// CHECK-NEXT: "command-line": [126// CHECK: ],127// Here is the actual check that this module X (which imports different version of Y)128// also has a different context hash from the first version of module X.129// CHECK-NOT: "context-hash": "[[HASH_X]]",130// CHECK: "file-deps": [131// CHECK-NEXT: "[[PREFIX]]/module.modulemap",132// CHECK-NEXT: "[[PREFIX]]/X.h"133// CHECK-NEXT: ],134// CHECK-NEXT: "link-libraries": [],135// CHECK-NEXT: "name": "X"136// CHECK-NEXT: },137// CHECK-NEXT: {138// CHECK-NEXT: "clang-module-deps": [],139// CHECK-NEXT: "clang-modulemap-file": "[[PREFIX]]/module.modulemap",140// CHECK-NEXT: "command-line": [141// CHECK: ],142// CHECK-NEXT: "context-hash": "[[HASH_Y_WITHOUT_A]]",143// CHECK-NEXT: "file-deps": [144// CHECK-NEXT: "[[PREFIX]]/module.modulemap",145// CHECK-NEXT: "[[PREFIX]]/Y.h",146// CHECK-NEXT: "[[PREFIX]]/begin/begin.h",147// CHECK-NEXT: "[[PREFIX]]/end/end.h"148// CHECK-NEXT: ],149// CHECK-NEXT: "link-libraries": [],150// CHECK-NEXT: "name": "Y"151// CHECK-NEXT: }152// CHECK-NEXT: ],153// CHECK-NEXT: "translation-units": [154// CHECK-NEXT: {155// CHECK: "clang-context-hash": "{{.*}}",156// CHECK-NEXT: "clang-module-deps": [157// CHECK-NEXT: {158// CHECK-NEXT: "context-hash": "{{.*}}",159// CHECK-NEXT: "module-name": "X"160// CHECK-NEXT: }161// CHECK-NEXT: ],162// CHECK-NEXT: "command-line": [163// CHECK: ],164// CHECK: "file-deps": [165// CHECK-NEXT: "[[PREFIX]]/test.c"166// CHECK-NEXT: ],167// CHECK-NEXT: "input-file": "[[PREFIX]]/test.c"168// CHECK-NEXT: }169