diff --git a/clang/include/clang/Basic/DiagnosticLexKinds.td b/clang/include/clang/Basic/DiagnosticLexKinds.td --- a/clang/include/clang/Basic/DiagnosticLexKinds.td +++ b/clang/include/clang/Basic/DiagnosticLexKinds.td @@ -888,6 +888,8 @@ InGroup>, DefaultError; def err_undeclared_use_of_module : Error< "module %0 does not depend on a module exporting '%1'">; +def err_undeclared_use_of_module_indirect : Error< + "module %0 does not directly depend on a module exporting '%1', which is part of indirectly-used module %2">; def warn_non_modular_include_in_framework_module : Warning< "include of non-modular header inside framework module '%0': '%1'">, InGroup, DefaultIgnore; diff --git a/clang/lib/Lex/ModuleMap.cpp b/clang/lib/Lex/ModuleMap.cpp --- a/clang/lib/Lex/ModuleMap.cpp +++ b/clang/lib/Lex/ModuleMap.cpp @@ -528,8 +528,9 @@ // We have found a module, but we don't use it. if (NotUsed) { - Diags.Report(FilenameLoc, diag::err_undeclared_use_of_module) - << RequestingModule->getTopLevelModule()->Name << Filename; + Diags.Report(FilenameLoc, diag::err_undeclared_use_of_module_indirect) + << RequestingModule->getTopLevelModule()->Name << Filename + << NotUsed->Name; return; } diff --git a/clang/test/Modules/Inputs/declare-use/h.h b/clang/test/Modules/Inputs/declare-use/h.h --- a/clang/test/Modules/Inputs/declare-use/h.h +++ b/clang/test/Modules/Inputs/declare-use/h.h @@ -1,7 +1,7 @@ #ifndef H_H #define H_H #include "c.h" -#include "d.h" // expected-error {{module XH does not depend on a module exporting}} +#include "d.h" // expected-error {{module XH does not directly depend on a module exporting 'd.h', which is part of indirectly-used module XD}} #include "h1.h" const int h1 = aux_h*c*7*d; #endif diff --git a/clang/test/Modules/declare-use-textual.cpp b/clang/test/Modules/declare-use-textual.cpp --- a/clang/test/Modules/declare-use-textual.cpp +++ b/clang/test/Modules/declare-use-textual.cpp @@ -2,5 +2,5 @@ // RUN: %clang_cc1 -fimplicit-module-maps -fmodules-cache-path=%t -fmodules-decluse -fmodule-name=Textual -I %S/Inputs/declare-use %s -verify // RUN: %clang_cc1 -fimplicit-module-maps -fmodules-cache-path=%t -fmodules-decluse -fmodule-name=Textual -I %S/Inputs/declare-use %s -fno-modules-validate-textual-header-includes -// expected-error@textual.h:* {{module Textual does not depend on a module exporting 'a.h'}} +// expected-error@textual.h:* {{module Textual does not directly depend on a module exporting 'a.h', which is part of indirectly-used module XA}} #include "textual.h" diff --git a/clang/test/Modules/declare-use1.cpp b/clang/test/Modules/declare-use1.cpp --- a/clang/test/Modules/declare-use1.cpp +++ b/clang/test/Modules/declare-use1.cpp @@ -6,7 +6,7 @@ #include "g.h" #include "e.h" -#include "f.h" // expected-error {{module XG does not depend on a module exporting 'f.h'}} +#include "f.h" // expected-error {{module XG does not directly depend on a module exporting 'f.h', which is part of indirectly-used module XF}} #include "i.h" #include "sub.h" const int g2 = g1 + e + f + aux_i + sub; diff --git a/clang/test/Modules/declare-use2.cpp b/clang/test/Modules/declare-use2.cpp --- a/clang/test/Modules/declare-use2.cpp +++ b/clang/test/Modules/declare-use2.cpp @@ -3,5 +3,5 @@ #include "h.h" #include "e.h" -#include "f.h" // expected-error {{module XH does not depend on a module exporting 'f.h'}} +#include "f.h" // expected-error {{module XH does not directly depend on a module exporting 'f.h', which is part of indirectly-used module XF}} const int h2 = h1+e+f; diff --git a/clang/test/Modules/declare-use3.cpp b/clang/test/Modules/declare-use3.cpp --- a/clang/test/Modules/declare-use3.cpp +++ b/clang/test/Modules/declare-use3.cpp @@ -1,4 +1,4 @@ // RUN: rm -rf %t // RUN: %clang_cc1 -include "g.h" -include "e.h" -include "f.h" -include "i.h" -fimplicit-module-maps -fmodules-cache-path=%t -fmodules-decluse -fmodule-name=XG -I %S/Inputs/declare-use %s -verify -// expected-error {{module XG does not depend on a module exporting 'f.h'}} +// expected-error {{module XG does not directly depend on a module exporting 'f.h', which is part of indirectly-used module XF}} const int g2 = g1 + e + f + aux_i; diff --git a/clang/test/Modules/strict-decluse.cpp b/clang/test/Modules/strict-decluse.cpp --- a/clang/test/Modules/strict-decluse.cpp +++ b/clang/test/Modules/strict-decluse.cpp @@ -3,7 +3,7 @@ #include "g.h" #include "e.h" -#include "f.h" // expected-error {{module XG does not depend on a module exporting 'f.h'}} +#include "f.h" // expected-error {{module XG does not directly depend on a module exporting 'f.h', which is part of indirectly-used module XF}} #include "i.h" // expected-error {{module XG does not depend on a module exporting 'i.h'}} const int g2 = g1 + e + f + aux_i; diff --git a/clang/test/Modules/string_names.cpp b/clang/test/Modules/string_names.cpp --- a/clang/test/Modules/string_names.cpp +++ b/clang/test/Modules/string_names.cpp @@ -6,5 +6,5 @@ // RUN: %clang_cc1 -fmodules -fimplicit-module-maps -fmodules-decluse -I %S/Inputs/string_names %t/test.ii -fmodule-name="my/module-a" #include "a.h" -#include "b.h" // expected-error {{does not depend on a module exporting}} +#include "b.h" // expected-error {{module my/module-a does not directly depend on a module exporting 'b.h', which is part of indirectly-used module my/module-b}} #include "c.h" diff --git a/clang/test/Modules/textual-headers.cpp b/clang/test/Modules/textual-headers.cpp --- a/clang/test/Modules/textual-headers.cpp +++ b/clang/test/Modules/textual-headers.cpp @@ -6,9 +6,9 @@ #include "k.h" #define GIMME_AN_L -#include "l.h" // expected-error {{module XG does not depend on a module exporting 'l.h'}} +#include "l.h" // expected-error {{module XG does not directly depend on a module exporting 'l.h', which is part of indirectly-used module XL}} -#include "m2.h" // expected-error {{module XG does not depend on a module exporting 'm2.h'}} +#include "m2.h" // expected-error {{module XG does not directly depend on a module exporting 'm2.h', which is part of indirectly-used module XM}} const int use_m = m; // expected-error {{undeclared identifier}} #define GIMME_AN_M