[clang] 0a088ea - Improve diagnostics for missing import / #include of module.
Richard Smith via cfe-commits
cfe-commits at lists.llvm.org
Tue Apr 28 18:41:33 PDT 2020
Author: Richard Smith
Date: 2020-04-28T18:41:14-07:00
New Revision: 0a088ead85fae11bb41d8a93ebe213db5554f087
URL: https://github.com/llvm/llvm-project/commit/0a088ead85fae11bb41d8a93ebe213db5554f087
DIFF: https://github.com/llvm/llvm-project/commit/0a088ead85fae11bb41d8a93ebe213db5554f087.diff
LOG: Improve diagnostics for missing import / #include of module.
Fix a few bugs where we would fail to properly determine header to
module correspondence when determining whether to suggest a #include or
import, and suggest a #include more often in language modes where there
is no import syntax. Generally, if the target is in a header with
include guards or #pragma once, we should suggest either #including or
importing that header, and not importing a module that happens to
textually include it.
In passing, improve the notes we attach to the corresponding
diagnostics: calling an entity that we couldn't see "previous" is
confusing.
Added:
Modified:
clang/include/clang/Basic/DiagnosticSemaKinds.td
clang/include/clang/Lex/HeaderSearch.h
clang/include/clang/Lex/ModuleMap.h
clang/include/clang/Lex/Preprocessor.h
clang/lib/Lex/HeaderSearch.cpp
clang/lib/Lex/ModuleMap.cpp
clang/lib/Lex/PPDirectives.cpp
clang/lib/Sema/SemaLookup.cpp
clang/lib/Serialization/ASTWriter.cpp
clang/test/CXX/basic/basic.scope/basic.scope.namespace/p2.cpp
clang/test/CXX/module/module.unit/p8.cpp
clang/test/CXX/modules-ts/dcl.dcl/dcl.module/dcl.module.import/p1.cpp
clang/test/Modules/auto-module-import.m
clang/test/Modules/cxx-templates.cpp
clang/test/Modules/decldef.m
clang/test/Modules/decldef.mm
clang/test/Modules/diagnose-missing-import.m
clang/test/Modules/interface-diagnose-missing-import.m
clang/test/Modules/ms-enums.cpp
clang/test/Modules/no-module-map.cpp
clang/test/Modules/normal-module-map.cpp
clang/test/Modules/stddef.c
clang/test/Modules/subframeworks.m
clang/test/Modules/submodule-visibility-cycles.cpp
clang/test/Modules/submodule-visibility.cpp
clang/test/Modules/submodules-merge-defs.cpp
clang/test/Modules/submodules.cpp
clang/test/Modules/suggest-include.cpp
clang/test/Modules/tag-injection.c
clang/test/Modules/tag-injection.cpp
clang/test/Modules/template-default-args.cpp
clang/test/Modules/undefined-type-fixit1.cpp
clang/test/Modules/visibility-in-instantiation.cpp
clang/test/SemaCXX/compare-modules-cxx2a.cpp
clang/test/SemaCXX/modules-ts.cppm
clang/tools/libclang/Indexing.cpp
Removed:
################################################################################
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index c0316f5d7834..9bf63307a4ed 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -10298,11 +10298,6 @@ def err_module_unimported_use : Error<
"explicit specialization|partial specialization}0 of %1 must be imported "
"from module '%2' before it is required">;
def err_module_unimported_use_header : Error<
- "missing '#include %3'; "
- "%select{declaration|definition|default argument|"
- "explicit specialization|partial specialization}0 of %1 must be imported "
- "from module '%2' before it is required">;
-def err_module_unimported_use_global_module_fragment : Error<
"%select{missing '#include'|missing '#include %3'}2; "
"%select{||default argument of |explicit specialization of |"
"partial specialization of }0%1 must be "
@@ -10312,6 +10307,10 @@ def err_module_unimported_use_multiple : Error<
"%select{declaration|definition|default argument|"
"explicit specialization|partial specialization}0 of %1 must be imported "
"from one of the following modules before it is required:%2">;
+def note_unreachable_entity : Note<
+ "%select{declaration|definition|default argument declared|"
+ "explicit specialization declared|partial specialization declared}0 here "
+ "is not %select{visible|reachable|reachable|reachable|reachable|reachable}0">;
def ext_module_import_in_extern_c : ExtWarn<
"import of C++ module '%0' appears within extern \"C\" language linkage "
"specification">, DefaultError,
diff --git a/clang/include/clang/Lex/HeaderSearch.h b/clang/include/clang/Lex/HeaderSearch.h
index b3113372a1d3..28c57dbe3b8e 100644
--- a/clang/include/clang/Lex/HeaderSearch.h
+++ b/clang/include/clang/Lex/HeaderSearch.h
@@ -476,6 +476,13 @@ class HeaderSearch {
/// This routine does not consider the effect of \#import
bool isFileMultipleIncludeGuarded(const FileEntry *File);
+ /// Determine whether the given file is known to have ever been \#imported
+ /// (or if it has been \#included and we've encountered a \#pragma once).
+ bool hasFileBeenImported(const FileEntry *File) {
+ const HeaderFileInfo *FI = getExistingFileInfo(File);
+ return FI && FI->isImport;
+ }
+
/// This method returns a HeaderMap for the specified
/// FileEntry, uniquing them through the 'HeaderMaps' datastructure.
const HeaderMap *CreateHeaderMap(const FileEntry *FE);
@@ -559,6 +566,12 @@ class HeaderSearch {
ModuleMap::KnownHeader findModuleForHeader(const FileEntry *File,
bool AllowTextual = false) const;
+ /// Retrieve all the modules corresponding to the given file.
+ ///
+ /// \ref findModuleForHeader should typically be used instead of this.
+ ArrayRef<ModuleMap::KnownHeader>
+ findAllModulesForHeader(const FileEntry *File) const;
+
/// Read the contents of the given module map file.
///
/// \param File The module map file.
diff --git a/clang/include/clang/Lex/ModuleMap.h b/clang/include/clang/Lex/ModuleMap.h
index 454fb3e01c88..805cc1f5017b 100644
--- a/clang/include/clang/Lex/ModuleMap.h
+++ b/clang/include/clang/Lex/ModuleMap.h
@@ -419,7 +419,10 @@ class ModuleMap {
Callbacks.push_back(std::move(Callback));
}
- /// Retrieve the module that owns the given header file, if any.
+ /// Retrieve the module that owns the given header file, if any. Note that
+ /// this does not implicitly load module maps, except for builtin headers,
+ /// and does not consult the external source. (Those checks are the
+ /// responsibility of \ref HeaderSearch.)
///
/// \param File The header file that is likely to be included.
///
@@ -433,13 +436,19 @@ class ModuleMap {
KnownHeader findModuleForHeader(const FileEntry *File,
bool AllowTextual = false);
- /// Retrieve all the modules that contain the given header file. This
- /// may not include umbrella modules, nor information from external sources,
- /// if they have not yet been inferred / loaded.
+ /// Retrieve all the modules that contain the given header file. Note that
+ /// this does not implicitly load module maps, except for builtin headers,
+ /// and does not consult the external source. (Those checks are the
+ /// responsibility of \ref HeaderSearch.)
///
/// Typically, \ref findModuleForHeader should be used instead, as it picks
/// the preferred module for the header.
- ArrayRef<KnownHeader> findAllModulesForHeader(const FileEntry *File) const;
+ ArrayRef<KnownHeader> findAllModulesForHeader(const FileEntry *File);
+
+ /// Like \ref findAllModulesForHeader, but do not attempt to infer module
+ /// ownership from umbrella headers if we've not already done so.
+ ArrayRef<KnownHeader>
+ findResolvedModulesForHeader(const FileEntry *File) const;
/// Resolve all lazy header directives for the specified file.
///
diff --git a/clang/include/clang/Lex/Preprocessor.h b/clang/include/clang/Lex/Preprocessor.h
index 61e5974c1f0d..7d358bded6e7 100644
--- a/clang/include/clang/Lex/Preprocessor.h
+++ b/clang/include/clang/Lex/Preprocessor.h
@@ -2278,20 +2278,22 @@ class Preprocessor {
/// into a module, or is outside any module, returns nullptr.
Module *getModuleForLocation(SourceLocation Loc);
- /// We want to produce a diagnostic at location IncLoc concerning a
- /// missing module import.
- ///
- /// \param IncLoc The location at which the missing import was detected.
- /// \param M The desired module.
- /// \param MLoc A location within the desired module at which some desired
- /// effect occurred (eg, where a desired entity was declared).
- ///
- /// \return A file that can be #included to import a module containing MLoc.
- /// Null if no such file could be determined or if a #include is not
- /// appropriate.
- const FileEntry *getModuleHeaderToIncludeForDiagnostics(SourceLocation IncLoc,
- Module *M,
- SourceLocation MLoc);
+ /// We want to produce a diagnostic at location IncLoc concerning an
+ /// unreachable effect at location MLoc (eg, where a desired entity was
+ /// declared or defined). Determine whether the right way to make MLoc
+ /// reachable is by #include, and if so, what header should be included.
+ ///
+ /// This is not necessarily fast, and might load unexpected module maps, so
+ /// should only be called by code that intends to produce an error.
+ ///
+ /// \param IncLoc The location at which the missing effect was detected.
+ /// \param MLoc A location within an unimported module at which the desired
+ /// effect occurred.
+ /// \return A file that can be #included to provide the desired effect. Null
+ /// if no such file could be determined or if a #include is not
+ /// appropriate (eg, if a module should be imported instead).
+ const FileEntry *getHeaderToIncludeForDiagnostics(SourceLocation IncLoc,
+ SourceLocation MLoc);
bool isRecordingPreamble() const {
return PreambleConditionalStack.isRecording();
diff --git a/clang/lib/Lex/HeaderSearch.cpp b/clang/lib/Lex/HeaderSearch.cpp
index 1199f75f8a3c..3ac1df1740c8 100644
--- a/clang/lib/Lex/HeaderSearch.cpp
+++ b/clang/lib/Lex/HeaderSearch.cpp
@@ -1219,9 +1219,11 @@ HeaderSearch::getExistingFileInfo(const FileEntry *FE,
}
bool HeaderSearch::isFileMultipleIncludeGuarded(const FileEntry *File) {
- // Check if we've ever seen this file as a header.
+ // Check if we've entered this file and found an include guard or #pragma
+ // once. Note that we dor't check for #import, because that's not a property
+ // of the file itself.
if (auto *HFI = getExistingFileInfo(File))
- return HFI->isPragmaOnce || HFI->isImport || HFI->ControllingMacro ||
+ return HFI->isPragmaOnce || HFI->ControllingMacro ||
HFI->ControllingMacroID;
return false;
}
@@ -1399,6 +1401,16 @@ HeaderSearch::findModuleForHeader(const FileEntry *File,
return ModMap.findModuleForHeader(File, AllowTextual);
}
+ArrayRef<ModuleMap::KnownHeader>
+HeaderSearch::findAllModulesForHeader(const FileEntry *File) const {
+ if (ExternalSource) {
+ // Make sure the external source has handled header info about this file,
+ // which includes whether the file is part of a module.
+ (void)getExistingFileInfo(File);
+ }
+ return ModMap.findAllModulesForHeader(File);
+}
+
static bool suggestModule(HeaderSearch &HS, const FileEntry *File,
Module *RequestingModule,
ModuleMap::KnownHeader *SuggestedModule) {
diff --git a/clang/lib/Lex/ModuleMap.cpp b/clang/lib/Lex/ModuleMap.cpp
index 4f7d5ab137e6..85bf93ac9949 100644
--- a/clang/lib/Lex/ModuleMap.cpp
+++ b/clang/lib/Lex/ModuleMap.cpp
@@ -662,7 +662,20 @@ ModuleMap::findOrCreateModuleForHeaderInUmbrellaDir(const FileEntry *File) {
}
ArrayRef<ModuleMap::KnownHeader>
-ModuleMap::findAllModulesForHeader(const FileEntry *File) const {
+ModuleMap::findAllModulesForHeader(const FileEntry *File) {
+ HeadersMap::iterator Known = findKnownHeader(File);
+ if (Known != Headers.end())
+ return Known->second;
+
+ if (findOrCreateModuleForHeaderInUmbrellaDir(File))
+ return Headers.find(File)->second;
+
+ return None;
+}
+
+ArrayRef<ModuleMap::KnownHeader>
+ModuleMap::findResolvedModulesForHeader(const FileEntry *File) const {
+ // FIXME: Is this necessary?
resolveHeaderDirectives(File);
auto It = Headers.find(File);
if (It == Headers.end())
diff --git a/clang/lib/Lex/PPDirectives.cpp b/clang/lib/Lex/PPDirectives.cpp
index d8041aef08ac..03bd36bfe267 100644
--- a/clang/lib/Lex/PPDirectives.cpp
+++ b/clang/lib/Lex/PPDirectives.cpp
@@ -646,24 +646,8 @@ Module *Preprocessor::getModuleForLocation(SourceLocation Loc) {
}
const FileEntry *
-Preprocessor::getModuleHeaderToIncludeForDiagnostics(SourceLocation IncLoc,
- Module *M,
- SourceLocation Loc) {
- assert(M && "no module to include");
-
- // If the context is the global module fragment of some module, we never
- // want to return that file; instead, we want the innermost include-guarded
- // header that it included.
- bool InGlobalModuleFragment = M->Kind == Module::GlobalModuleFragment;
-
- // If we have a module import syntax, we shouldn't include a header to
- // make a particular module visible.
- if ((getLangOpts().ObjC || getLangOpts().CPlusPlusModules ||
- getLangOpts().ModulesTS) &&
- !InGlobalModuleFragment)
- return nullptr;
-
- Module *TopM = M->getTopLevelModule();
+Preprocessor::getHeaderToIncludeForDiagnostics(SourceLocation IncLoc,
+ SourceLocation Loc) {
Module *IncM = getModuleForLocation(IncLoc);
// Walk up through the include stack, looking through textual headers of M
@@ -677,37 +661,50 @@ Preprocessor::getModuleHeaderToIncludeForDiagnostics(SourceLocation IncLoc,
if (!FE)
break;
- if (InGlobalModuleFragment) {
- if (getHeaderSearchInfo().isFileMultipleIncludeGuarded(FE))
- return FE;
- Loc = SM.getIncludeLoc(ID);
- continue;
- }
-
- bool InTextualHeader = false;
- for (auto Header : HeaderInfo.getModuleMap().findAllModulesForHeader(FE)) {
- if (!Header.getModule()->isSubModuleOf(TopM))
- continue;
-
- if (!(Header.getRole() & ModuleMap::TextualHeader)) {
- // If this is an accessible, non-textual header of M's top-level module
- // that transitively includes the given location and makes the
- // corresponding module visible, this is the thing to #include.
- if (Header.isAccessibleFrom(IncM))
- return FE;
+ // We want to find all possible modules that might contain this header, so
+ // search all enclosing directories for module maps and load them.
+ HeaderInfo.hasModuleMap(FE->getName(), /*Root*/ nullptr,
+ SourceMgr.isInSystemHeader(Loc));
+ bool InPrivateHeader = false;
+ for (auto Header : HeaderInfo.findAllModulesForHeader(FE)) {
+ if (!Header.isAccessibleFrom(IncM)) {
// It's in a private header; we can't #include it.
// FIXME: If there's a public header in some module that re-exports it,
// then we could suggest including that, but it's not clear that's the
// expected way to make this entity visible.
+ InPrivateHeader = true;
continue;
}
- InTextualHeader = true;
+ // We'll suggest including textual headers below if they're
+ // include-guarded.
+ if (Header.getRole() & ModuleMap::TextualHeader)
+ continue;
+
+ // If we have a module import syntax, we shouldn't include a header to
+ // make a particular module visible. Let the caller know they should
+ // suggest an import instead.
+ if (getLangOpts().ObjC || getLangOpts().CPlusPlusModules ||
+ getLangOpts().ModulesTS)
+ return nullptr;
+
+ // If this is an accessible, non-textual header of M's top-level module
+ // that transitively includes the given location and makes the
+ // corresponding module visible, this is the thing to #include.
+ return FE;
}
- if (!InTextualHeader)
- break;
+ // FIXME: If we're bailing out due to a private header, we shouldn't suggest
+ // an import either.
+ if (InPrivateHeader)
+ return nullptr;
+
+ // If the header is includable and has an include guard, assume the
+ // intended way to expose its contents is by #include, not by importing a
+ // module that transitively includes it.
+ if (getHeaderSearchInfo().isFileMultipleIncludeGuarded(FE))
+ return FE;
Loc = SM.getIncludeLoc(ID);
}
diff --git a/clang/lib/Sema/SemaLookup.cpp b/clang/lib/Sema/SemaLookup.cpp
index 08d29fa51e6e..aa83f82a1ce8 100644
--- a/clang/lib/Sema/SemaLookup.cpp
+++ b/clang/lib/Sema/SemaLookup.cpp
@@ -5350,9 +5350,8 @@ void Sema::diagnoseMissingImport(SourceLocation Loc, NamedDecl *Decl,
/// Get a "quoted.h" or <angled.h> include path to use in a diagnostic
/// suggesting the addition of a #include of the specified file.
-static std::string getIncludeStringForHeader(Preprocessor &PP,
- const FileEntry *E,
- llvm::StringRef IncludingFile) {
+static std::string getHeaderNameForHeader(Preprocessor &PP, const FileEntry *E,
+ llvm::StringRef IncludingFile) {
bool IsSystem = false;
auto Path = PP.getHeaderSearchInfo().suggestPathToFileForDiagnostics(
E, IncludingFile, &IsSystem);
@@ -5366,25 +5365,10 @@ void Sema::diagnoseMissingImport(SourceLocation UseLoc, NamedDecl *Decl,
assert(!Modules.empty());
auto NotePrevious = [&] {
- unsigned DiagID;
- switch (MIK) {
- case MissingImportKind::Declaration:
- DiagID = diag::note_previous_declaration;
- break;
- case MissingImportKind::Definition:
- DiagID = diag::note_previous_definition;
- break;
- case MissingImportKind::DefaultArgument:
- DiagID = diag::note_default_argument_declared_here;
- break;
- case MissingImportKind::ExplicitSpecialization:
- DiagID = diag::note_explicit_specialization_declared_here;
- break;
- case MissingImportKind::PartialSpecialization:
- DiagID = diag::note_partial_specialization_declared_here;
- break;
- }
- Diag(DeclLoc, DiagID);
+ // FIXME: Suppress the note backtrace even under
+ // -fdiagnostics-show-note-include-stack. We don't care how this
+ // declaration was previously reached.
+ Diag(DeclLoc, diag::note_unreachable_entity) << (int)MIK;
};
// Weed out duplicates from module list.
@@ -5397,26 +5381,24 @@ void Sema::diagnoseMissingImport(SourceLocation UseLoc, NamedDecl *Decl,
UniqueModules.push_back(M);
}
- llvm::StringRef IncludingFile;
- if (const FileEntry *FE =
- SourceMgr.getFileEntryForID(SourceMgr.getFileID(UseLoc)))
- IncludingFile = FE->tryGetRealPathName();
+ // Try to find a suitable header-name to #include.
+ std::string HeaderName;
+ if (const FileEntry *Header =
+ PP.getHeaderToIncludeForDiagnostics(UseLoc, DeclLoc)) {
+ if (const FileEntry *FE =
+ SourceMgr.getFileEntryForID(SourceMgr.getFileID(UseLoc)))
+ HeaderName = getHeaderNameForHeader(PP, Header, FE->tryGetRealPathName());
+ }
- if (UniqueModules.empty()) {
- // All candidates were global module fragments. Try to suggest a #include.
- const FileEntry *E =
- PP.getModuleHeaderToIncludeForDiagnostics(UseLoc, Modules[0], DeclLoc);
+ // If we have a #include we should suggest, or if all definition locations
+ // were in global module fragments, don't suggest an import.
+ if (!HeaderName.empty() || UniqueModules.empty()) {
// FIXME: Find a smart place to suggest inserting a #include, and add
// a FixItHint there.
- Diag(UseLoc, diag::err_module_unimported_use_global_module_fragment)
- << (int)MIK << Decl << !!E
- << (E ? getIncludeStringForHeader(PP, E, IncludingFile) : "");
- // Produce a "previous" note if it will point to a header rather than some
- // random global module fragment.
- // FIXME: Suppress the note backtrace even under
- // -fdiagnostics-show-note-include-stack.
- if (E)
- NotePrevious();
+ Diag(UseLoc, diag::err_module_unimported_use_header)
+ << (int)MIK << Decl << !HeaderName.empty() << HeaderName;
+ // Produce a note showing where the entity was declared.
+ NotePrevious();
if (Recover)
createImplicitModuleImportForErrorRecovery(UseLoc, Modules[0]);
return;
@@ -5438,16 +5420,6 @@ void Sema::diagnoseMissingImport(SourceLocation UseLoc, NamedDecl *Decl,
Diag(UseLoc, diag::err_module_unimported_use_multiple)
<< (int)MIK << Decl << ModuleList;
- } else if (const FileEntry *E = PP.getModuleHeaderToIncludeForDiagnostics(
- UseLoc, Modules[0], DeclLoc)) {
- // The right way to make the declaration visible is to include a header;
- // suggest doing so.
- //
- // FIXME: Find a smart place to suggest inserting a #include, and add
- // a FixItHint there.
- Diag(UseLoc, diag::err_module_unimported_use_header)
- << (int)MIK << Decl << Modules[0]->getFullModuleName()
- << getIncludeStringForHeader(PP, E, IncludingFile);
} else {
// FIXME: Add a FixItHint that imports the corresponding module.
Diag(UseLoc, diag::err_module_unimported_use)
diff --git a/clang/lib/Serialization/ASTWriter.cpp b/clang/lib/Serialization/ASTWriter.cpp
index 03121515a5cc..748ac06c5643 100644
--- a/clang/lib/Serialization/ASTWriter.cpp
+++ b/clang/lib/Serialization/ASTWriter.cpp
@@ -1812,7 +1812,7 @@ void ASTWriter::WriteHeaderSearch(const HeaderSearch &HS) {
Filename, File->getSize(), getTimestampForOutput(File)
};
HeaderFileInfoTrait::data_type Data = {
- *HFI, HS.getModuleMap().findAllModulesForHeader(File), {}
+ *HFI, HS.getModuleMap().findResolvedModulesForHeader(File), {}
};
Generator.insert(Key, Data, GeneratorTrait);
++NumHeaderSearchEntries;
diff --git a/clang/test/CXX/basic/basic.scope/basic.scope.namespace/p2.cpp b/clang/test/CXX/basic/basic.scope/basic.scope.namespace/p2.cpp
index 55c5ce6c4cbe..79529c6c0fc0 100644
--- a/clang/test/CXX/basic/basic.scope/basic.scope.namespace/p2.cpp
+++ b/clang/test/CXX/basic/basic.scope/basic.scope.namespace/p2.cpp
@@ -11,6 +11,8 @@
#ifdef INTERFACE
module;
#include "foo.h"
+// FIXME: The following need to be moved to a header file. The global module
+// fragment is only permitted to contain preprocessor directives.
int global_module_fragment;
export module A;
export int exported;
@@ -28,12 +30,13 @@ module;
void test_early() {
in_header = 1; // expected-error {{missing '#include "foo.h"'; 'in_header' must be declared before it is used}}
- // expected-note@*{{previous}}
+ // expected-note@*{{not visible}}
global_module_fragment = 1; // expected-error {{missing '#include'; 'global_module_fragment' must be declared before it is used}}
+ // expected-note at p2.cpp:16 {{not visible}}
exported = 1; // expected-error {{must be imported from module 'A'}}
- // expected-note at p2.cpp:16 {{previous}}
+ // expected-note at p2.cpp:18 {{not visible}}
not_exported = 1; // expected-error {{undeclared identifier}}
@@ -52,16 +55,17 @@ import A;
void test_late() {
in_header = 1; // expected-error {{missing '#include "foo.h"'; 'in_header' must be declared before it is used}}
- // expected-note@*{{previous}}
+ // expected-note@*{{not visible}}
global_module_fragment = 1; // expected-error {{missing '#include'; 'global_module_fragment' must be declared before it is used}}
+ // expected-note at p2.cpp:16 {{not visible}}
exported = 1;
not_exported = 1;
#ifndef IMPLEMENTATION
// expected-error at -2 {{undeclared identifier 'not_exported'; did you mean 'exported'}}
- // expected-note at p2.cpp:16 {{declared here}}
+ // expected-note at p2.cpp:18 {{declared here}}
#endif
internal = 1;
diff --git a/clang/test/CXX/module/module.unit/p8.cpp b/clang/test/CXX/module/module.unit/p8.cpp
index aad65272f0d6..a4a85d0bf91f 100644
--- a/clang/test/CXX/module/module.unit/p8.cpp
+++ b/clang/test/CXX/module/module.unit/p8.cpp
@@ -36,5 +36,5 @@ export module foo:bar; // expected-error {{not yet supported}} expected-error {{
int k = n;
#ifndef IMPORTED
// expected-error at -2 {{declaration of 'n' must be imported from module 'foo' before it is required}}
-// expected-note@* {{previous}}
+// expected-note@* {{not visible}}
#endif
diff --git a/clang/test/CXX/modules-ts/dcl.dcl/dcl.module/dcl.module.import/p1.cpp b/clang/test/CXX/modules-ts/dcl.dcl/dcl.module/dcl.module.import/p1.cpp
index 15900c1f6a3a..70b553f1ff74 100644
--- a/clang/test/CXX/modules-ts/dcl.dcl/dcl.module/dcl.module.import/p1.cpp
+++ b/clang/test/CXX/modules-ts/dcl.dcl/dcl.module/dcl.module.import/p1.cpp
@@ -23,7 +23,7 @@ module MODULE_NAME;
int use_1 = a;
#if !MODULE_X
// expected-error at -2 {{declaration of 'a' must be imported from module 'x' before it is required}}
-// expected-note at x.cppm:1 {{here}}
+// expected-note at x.cppm:1 {{not visible}}
#endif
import x;
@@ -32,7 +32,7 @@ int use_2 = b; // ok
// There is no relation between module x and module x.y.
int use_3 = c; // expected-error {{declaration of 'c' must be imported from module 'x.y'}}
- // expected-note at x.y.cppm:1 {{here}}
+ // expected-note at x.y.cppm:1 {{not visible}}
import x [[]];
import x [[foo]]; // expected-warning {{unknown attribute 'foo' ignored}}
diff --git a/clang/test/Modules/auto-module-import.m b/clang/test/Modules/auto-module-import.m
index f6127adcbd89..7b90e867d437 100644
--- a/clang/test/Modules/auto-module-import.m
+++ b/clang/test/Modules/auto-module-import.m
@@ -18,7 +18,7 @@
#ifdef ERRORS
Module *mod; // expected-error{{declaration of 'Module' must be imported from module 'Module' before it is required}}
-// expected-note at Inputs/Module.framework/Headers/Module.h:15 {{previous}}
+// expected-note at Inputs/Module.framework/Headers/Module.h:15 {{not visible}}
#else
#import <AlsoDependsOnModule/AlsoDependsOnModule.h> // expected-warning{{treating #import as an import of module 'AlsoDependsOnModule'}}
#endif
@@ -29,7 +29,7 @@
void testSubframeworkOther() {
#ifdef ERRORS
double *sfo1 = sub_framework_other; // expected-error{{declaration of 'sub_framework_other' must be imported from module 'DependsOnModule.SubFramework.Other'}}
- // expected-note at Inputs/DependsOnModule.framework/Frameworks/SubFramework.framework/Headers/Other.h:15 {{previous}}
+ // expected-note at Inputs/DependsOnModule.framework/Frameworks/SubFramework.framework/Headers/Other.h:15 {{not visible}}
#endif
}
@@ -73,7 +73,7 @@ void testModuleSubFrameworkAgain() {
int getNoUmbrellaAPrivate() { return no_umbrella_A_private; }
int getNoUmbrellaBPrivateFail() { return no_umbrella_B_private; } // expected-error{{declaration of 'no_umbrella_B_private' must be imported from module 'NoUmbrella.Private.B_Private'}}
-// expected-note at Inputs/NoUmbrella.framework/PrivateHeaders/B_Private.h:1 {{previous}}
+// expected-note at Inputs/NoUmbrella.framework/PrivateHeaders/B_Private.h:1 {{not visible}}
// Test inclusion of headers that are under an umbrella directory but
// not actually part of the module.
diff --git a/clang/test/Modules/cxx-templates.cpp b/clang/test/Modules/cxx-templates.cpp
index c085eb5f676c..5bb3ca338051 100644
--- a/clang/test/Modules/cxx-templates.cpp
+++ b/clang/test/Modules/cxx-templates.cpp
@@ -83,7 +83,7 @@ void g() {
// a big spew of errors here.
//
// expected-error at Inputs/cxx-templates-a.h:19 {{definition of 'DefinedInBImpl' must be imported}}
- // expected-note at Inputs/cxx-templates-b-impl.h:1 +{{definition is here}}
+ // expected-note at Inputs/cxx-templates-b-impl.h:1 +{{definition here is not reachable}}
// expected-error at Inputs/cxx-templates-a.h:19 +{{}}
// expected-error at Inputs/cxx-templates-a.h:20 +{{}}
PerformDelayedLookup(defined_in_b_impl); // expected-note {{in instantiation of}}
@@ -106,8 +106,8 @@ void g() {
TemplateInstantiationVisibility<char[1]> tiv1;
TemplateInstantiationVisibility<char[2]> tiv2;
TemplateInstantiationVisibility<char[3]> tiv3; // expected-error 5{{must be imported from module 'cxx_templates_b_impl'}}
- // expected-note at cxx-templates-b-impl.h:10 3{{explicit specialization declared here}}
- // expected-note at cxx-templates-b-impl.h:10 2{{previous definition is here}}
+ // expected-note at cxx-templates-b-impl.h:10 3{{explicit specialization declared here is not reachable}}
+ // expected-note at cxx-templates-b-impl.h:10 2{{definition here is not reachable}}
TemplateInstantiationVisibility<char[4]> tiv4;
int &p = WithPartialSpecializationUse().f();
diff --git a/clang/test/Modules/decldef.m b/clang/test/Modules/decldef.m
index 784743ff6e79..1fb9bdf58455 100644
--- a/clang/test/Modules/decldef.m
+++ b/clang/test/Modules/decldef.m
@@ -2,7 +2,7 @@
// RUN: %clang_cc1 -fmodules -fimplicit-module-maps -fobjc-arc -I %S/Inputs -fmodules-cache-path=%t %s -verify -DUSE_EARLY
// RUN: %clang_cc1 -fmodules -fimplicit-module-maps -fobjc-arc -I %S/Inputs -fmodules-cache-path=%t %s -verify
-// expected-note at Inputs/def.h:5 {{previous}}
+// expected-note at Inputs/def.h:5 {{here}}
@class Def;
Def *def;
@@ -16,7 +16,7 @@
// expected-error at -2{{must use 'struct' tag to refer to type 'B'}}
#else
// expected-error at -4{{declaration of 'B' must be imported from module 'decldef.Decl' before it is required}}
-// expected-note at Inputs/decl.h:2 {{previous}}
+// expected-note at Inputs/decl.h:2 {{not visible}}
#endif
@import decldef.Decl;
diff --git a/clang/test/Modules/decldef.mm b/clang/test/Modules/decldef.mm
index ab271fc2ba95..e8f070b51159 100644
--- a/clang/test/Modules/decldef.mm
+++ b/clang/test/Modules/decldef.mm
@@ -4,9 +4,9 @@
// RUN: %clang_cc1 -fmodules -fimplicit-module-maps -fobjc-arc -I %S/Inputs -fmodules-cache-path=%t %s -verify -DUSE_3 -DUSE_4
// RUN: %clang_cc1 -fmodules -fimplicit-module-maps -fobjc-arc -I %S/Inputs -fmodules-cache-path=%t %s -verify -DUSE_4
-// expected-note at Inputs/def.h:5 0-1{{previous}}
-// expected-note at Inputs/def.h:16 0-1{{previous}}
-// expected-note at Inputs/def-include.h:11 0-1{{previous}}
+// expected-note at Inputs/def.h:5 0-1{{here}}
+// expected-note at Inputs/def.h:16 0-1{{here}}
+// expected-note at Inputs/def-include.h:11 0-1{{here}}
@class Def;
Def *def;
diff --git a/clang/test/Modules/diagnose-missing-import.m b/clang/test/Modules/diagnose-missing-import.m
index e0c0457e6357..2c67e01944a9 100644
--- a/clang/test/Modules/diagnose-missing-import.m
+++ b/clang/test/Modules/diagnose-missing-import.m
@@ -8,7 +8,7 @@ void foo() {
XYZLogEvent(xyzRiskyCloseOpenParam, xyzRiskyCloseOpenParam); // expected-error {{implicit declaration of function 'XYZLogEvent'}} expected-error {{declaration of 'XYZLogEvent' must be imported}} expected-error {{declaration of 'xyzRiskyCloseOpenParam' must be imported from module 'NCI.A'}} expected-error {{declaration of 'xyzRiskyCloseOpenParam' must be imported from module 'NCI.A'}}
}
-// expected-note at Inputs/diagnose-missing-import/a.h:5 {{previous declaration is here}}
-// expected-note at Inputs/diagnose-missing-import/a.h:5 {{previous declaration is here}}
-// expected-note at Inputs/diagnose-missing-import/a.h:6 {{previous declaration is here}}
+// expected-note at Inputs/diagnose-missing-import/a.h:5 {{declaration here is not visible}}
+// expected-note at Inputs/diagnose-missing-import/a.h:5 {{declaration here is not visible}}
+// expected-note at Inputs/diagnose-missing-import/a.h:6 {{declaration here is not visible}}
diff --git a/clang/test/Modules/interface-diagnose-missing-import.m b/clang/test/Modules/interface-diagnose-missing-import.m
index 5bbac3642300..c455b1501c9c 100644
--- a/clang/test/Modules/interface-diagnose-missing-import.m
+++ b/clang/test/Modules/interface-diagnose-missing-import.m
@@ -8,4 +8,4 @@ @interface Buggy
@interface Buggy (MyExt) // expected-error {{definition of 'Buggy' must be imported from module 'Foo' before it is required}}
@end
-// expected-note at Foo/RandoPriv.h:3{{previous definition is here}}
+// expected-note at Foo/RandoPriv.h:3{{definition here is not reachable}}
diff --git a/clang/test/Modules/ms-enums.cpp b/clang/test/Modules/ms-enums.cpp
index b3a377c6fa63..da75d152ffa4 100644
--- a/clang/test/Modules/ms-enums.cpp
+++ b/clang/test/Modules/ms-enums.cpp
@@ -2,8 +2,8 @@
// RUN: %clang_cc1 -triple x86_64-windows-msvc -fms-extensions -fms-compatibility -x c++ -std=c++20 -fmodules-cache-path=%t -fmodules -fimplicit-module-maps -I %S/Inputs/ms-enums %s -verify -fno-modules-error-recovery
#include "B.h"
-// expected-note at A.h:1 {{previous declaration is here}}
-// expected-note at A.h:1 2 {{previous definition is here}}
+// expected-note at A.h:1 {{declaration here is not visible}}
+// expected-note at A.h:1 2{{definition here is not reachable}}
fwd_enum gv_enum; // expected-error {{must be imported}}
diff --git a/clang/test/Modules/no-module-map.cpp b/clang/test/Modules/no-module-map.cpp
index 46ca38af7eed..81533417e856 100644
--- a/clang/test/Modules/no-module-map.cpp
+++ b/clang/test/Modules/no-module-map.cpp
@@ -30,7 +30,7 @@
#error A_H should not be defined
#endif
// expected-error at +3 {{must be imported from}}
-// expected-note@* {{previous declaration}}
+// expected-note@* {{declaration}}
#endif
void use_a() { a(); }
@@ -43,6 +43,6 @@ void use_a() { a(); }
#error B_H should not be defined
#endif
// expected-error at +3 {{must be imported from}}
-// expected-note@* {{previous declaration}}
+// expected-note@* {{declaration}}
#endif
void use_b() { b(); }
diff --git a/clang/test/Modules/normal-module-map.cpp b/clang/test/Modules/normal-module-map.cpp
index 5db1f3f33e94..6b8befb77293 100644
--- a/clang/test/Modules/normal-module-map.cpp
+++ b/clang/test/Modules/normal-module-map.cpp
@@ -25,7 +25,7 @@ int testNestedUmbrellaA() {
int testNestedUmbrellaBFail() {
return nested_umbrella_b;
// expected-error at -1{{declaration of 'nested_umbrella_b' must be imported from module 'nested_umbrella.b' before it is required}}
- // expected-note at Inputs/normal-module-map/nested_umbrella/b.h:1{{previous}}
+ // expected-note at Inputs/normal-module-map/nested_umbrella/b.h:1{{here}}
}
@import nested_umbrella.b;
diff --git a/clang/test/Modules/stddef.c b/clang/test/Modules/stddef.c
index 16de854563fc..c33f3643112b 100644
--- a/clang/test/Modules/stddef.c
+++ b/clang/test/Modules/stddef.c
@@ -5,8 +5,8 @@
ptr
diff _t pdt;
-size_t st; // expected-error {{must be imported}}
-// expected-note at stddef.h:* {{previous}}
+size_t st; // expected-error {{missing '#include "include_again.h"'; 'size_t' must be declared before it is used}}
+// expected-note at stddef.h:* {{here}}
#include "include_again.h"
diff --git a/clang/test/Modules/subframeworks.m b/clang/test/Modules/subframeworks.m
index ce35415717d2..c4cf85a2babf 100644
--- a/clang/test/Modules/subframeworks.m
+++ b/clang/test/Modules/subframeworks.m
@@ -6,7 +6,7 @@
void testSubFramework() {
float *sf1 = sub_framework; // expected-error{{declaration of 'sub_framework' must be imported from module 'DependsOnModule.SubFramework' before it is required}}
- // expected-note at Inputs/DependsOnModule.framework/Frameworks/SubFramework.framework/Headers/SubFramework.h:2 {{previous}}
+ // expected-note at Inputs/DependsOnModule.framework/Frameworks/SubFramework.framework/Headers/SubFramework.h:2 {{here}}
}
@import DependsOnModule.SubFramework;
diff --git a/clang/test/Modules/submodule-visibility-cycles.cpp b/clang/test/Modules/submodule-visibility-cycles.cpp
index a01fe562b14f..4fecdb98abd1 100644
--- a/clang/test/Modules/submodule-visibility-cycles.cpp
+++ b/clang/test/Modules/submodule-visibility-cycles.cpp
@@ -3,7 +3,7 @@
#include "cycle1.h"
C1 c1;
-C2 c2; // expected-error {{must be imported}}
+C2 c2; // expected-error {{missing '#include "cycle2.h"'; 'C2' must be declared}}
// expected-note at cycle2.h:6 {{here}}
#include "cycle2.h"
diff --git a/clang/test/Modules/submodule-visibility.cpp b/clang/test/Modules/submodule-visibility.cpp
index 4c066e6ab9b0..cae18d41ad7b 100644
--- a/clang/test/Modules/submodule-visibility.cpp
+++ b/clang/test/Modules/submodule-visibility.cpp
@@ -22,7 +22,7 @@
// The use of -fmodule-name=x causes us to textually include the above headers.
// The submodule visibility rules are still applied in this case.
//
-// expected-error at b.h:1 {{declaration of 'n' must be imported from module 'x.a'}}
+// expected-error at b.h:1 {{missing '#include "a.h"'; 'n' must be declared}}
// expected-note at a.h:1 {{here}}
#endif
diff --git a/clang/test/Modules/submodules-merge-defs.cpp b/clang/test/Modules/submodules-merge-defs.cpp
index 9e1ac6ceef28..777fe6936a43 100644
--- a/clang/test/Modules/submodules-merge-defs.cpp
+++ b/clang/test/Modules/submodules-merge-defs.cpp
@@ -15,67 +15,55 @@
#endif
A pre_a;
-#ifdef IMPORT_USE_2
-// expected-error-re at -2 {{must be imported from one of {{.*}}stuff.use{{.*}}stuff.use-2}}
-#elif EARLY_INDIRECT_INCLUDE
-// expected-error at -4 {{must be imported from module 'merged-defs'}}
-#else
-// expected-error at -6 {{must be imported from module 'stuff.use'}}
-#endif
+// expected-error-re at -1 {{missing '#include "{{.*}}-defs.h"'; 'A' must be declared}}
// expected-note at defs.h:1 +{{here}}
extern class A pre_a2;
-int pre_use_a = use_a(pre_a2); // expected-error 2{{'A' must be imported}} expected-error {{'use_a' must be imported}}
+int pre_use_a = use_a(pre_a2); // expected-error 2{{'A' must be defined}} expected-error {{'use_a' must be declared}}
// expected-note at defs.h:2 +{{here}}
-B::Inner2 pre_bi; // expected-error +{{must be imported}}
+B::Inner2 pre_bi; // expected-error +{{must be declared}} expected-error +{{must be defined}}
// expected-note at defs.h:4 +{{here}}
// expected-note at defs.h:17 +{{here}}
-void pre_bfi(B b) { // expected-error +{{must be imported}}
+void pre_bfi(B b) { // expected-error +{{must be declared}}
b.f<int>();
}
-C_Base<1> pre_cb1; // expected-error +{{must be imported}}
+C_Base<1> pre_cb1; // expected-error +{{must be declared}} expected-error +{{must be defined}}
// expected-note at defs.h:23 +{{here}}
-C1 pre_c1; // expected-error +{{must be imported}}
+C1 pre_c1; // expected-error +{{must be declared}}
// expected-note at defs.h:25 +{{here}}
-C2 pre_c2; // expected-error +{{must be imported}}
+C2 pre_c2; // expected-error +{{must be declared}}
// expected-note at defs.h:26 +{{here}}
-D::X pre_dx; // expected-error +{{must be imported}}
+D::X pre_dx; // expected-error +{{must be declared}} expected-error +{{must be defined}}
// expected-note at defs.h:28 +{{here}}
// expected-note at defs.h:29 +{{here}}
int pre_use_dx = use_dx(pre_dx); // ignored; pre_dx is invalid
-int pre_e = E(0); // expected-error {{must be imported}}
+int pre_e = E(0); // expected-error {{must be declared}}
// expected-note at defs.h:32 +{{here}}
-int pre_ff = F<int>().f(); // expected-error +{{must be imported}}
-int pre_fg = F<int>().g<int>(); // expected-error +{{must be imported}}
+int pre_ff = F<int>().f(); // expected-error +{{must be declared}}
+int pre_fg = F<int>().g<int>(); // expected-error +{{must be declared}}
// expected-note at defs.h:34 +{{here}}
-G::A pre_ga // expected-error +{{must be imported}}
- = G::a; // expected-error +{{must be imported}}
+G::A pre_ga // expected-error +{{must be declared}}
+ = G::a; // expected-error +{{must be declared}}
// expected-note at defs.h:49 +{{here}}
// expected-note at defs.h:50 +{{here}}
-decltype(G::h) pre_gh = G::h; // expected-error +{{must be imported}}
+decltype(G::h) pre_gh = G::h; // expected-error +{{must be declared}} expected-error +{{must be defined}}
// expected-note at defs.h:51 +{{here}}
-int pre_h = H(); // expected-error +{{must be imported}}
+int pre_h = H(); // expected-error +{{must be declared}}
// expected-note at defs.h:56 +{{here}}
-using pre_i = I<>; // expected-error +{{must be imported}}
+using pre_i = I<>; // expected-error +{{must be declared}} expected-error +{{default argument of 'I' must be defined}}
// expected-note at defs.h:57 +{{here}}
-J<> pre_j; // expected-error {{declaration of 'J' must be imported}}
-#ifdef IMPORT_USE_2
-// expected-error-re at -2 {{default argument of 'J' must be imported from one of {{.*}}stuff.use-2{{.*}}stuff.use}}
-#elif EARLY_INDIRECT_INCLUDE
-// expected-error at -4 {{default argument of 'J' must be imported from module 'merged-defs'}}
-#else
-// expected-error at -6 {{default argument of 'J' must be imported from module 'stuff.use'}}
-#endif
+J<> pre_j; // expected-error {{'J' must be declared}}
+// expected-error-re at -1 {{missing '#include "{{.*}}.h"'; default argument of 'J' must be defined before it is used}}
// expected-note at defs.h:58 +{{here}}
-ScopedEnum pre_scopedenum; // expected-error {{must be imported}}
+ScopedEnum pre_scopedenum; // expected-error {{must be declared}}
// expected-note at defs.h:105 0-1{{here}}
// expected-note at defs.h:106 0-1{{here}}
enum ScopedEnum : int;
diff --git a/clang/test/Modules/submodules.cpp b/clang/test/Modules/submodules.cpp
index a3dde23cb5b5..e4a31db0e533 100644
--- a/clang/test/Modules/submodules.cpp
+++ b/clang/test/Modules/submodules.cpp
@@ -8,8 +8,8 @@ vector<int> vi;
// Note: remove_reference is not visible yet.
remove_reference<int&>::type *int_ptr = 0; // expected-error{{declaration of 'remove_reference' must be imported from module 'std.type_traits' before it is required}}
-// expected-note at Inputs/submodules/type_traits.h:2{{previous}}
-// expected-note at Inputs/submodules/hash_map.h:1{{previous}}
+// expected-note at Inputs/submodules/type_traits.h:2{{not visible}}
+// expected-note at Inputs/submodules/hash_map.h:1{{not visible}}
@import std.typetraits; // expected-error{{no submodule named 'typetraits' in module 'std'; did you mean 'type_traits'?}}
diff --git a/clang/test/Modules/suggest-include.cpp b/clang/test/Modules/suggest-include.cpp
index e10c3f38aba2..1e53ef05d5f8 100644
--- a/clang/test/Modules/suggest-include.cpp
+++ b/clang/test/Modules/suggest-include.cpp
@@ -3,23 +3,25 @@
#include "empty.h" // import the module file
-// expected-note at usetextual1.h:2 {{previous}}
-// expected-note at textual2.h:1 {{previous}}
-// expected-note at textual3.h:1 {{previous}}
-// expected-note at textual4.h:1 {{previous}}
-// expected-note at textual5.h:1 {{previous}}
-// expected-note at private1.h:1 {{previous}}
-// expected-note at private2.h:1 {{previous}}
-// expected-note at private3.h:1 {{previous}}
+// expected-note at usetextual1.h:2 {{here}}
+// expected-note at textual2.h:1 {{here}}
+// expected-note at textual3.h:1 {{here}}
+// expected-note at textual4.h:1 {{here}}
+// expected-note at textual5.h:1 {{here}}
+// expected-note at private1.h:1 {{here}}
+// expected-note at private2.h:1 {{here}}
+// expected-note at private3.h:1 {{here}}
void f() {
(void)::usetextual1; // expected-error {{missing '#include "usetextual1.h"'}}
(void)::usetextual2; // expected-error {{missing '#include "usetextual2.h"'}}
(void)::textual3; // expected-error-re {{{{^}}missing '#include "usetextual3.h"'}}
- // Don't suggest a #include that includes the entity via a path that leaves
- // the module. In that case we can't be sure that we've picked the right header.
- (void)::textual4; // expected-error-re {{{{^}}declaration of 'textual4'}}
- (void)::textual5; // expected-error-re {{{{^}}declaration of 'textual5'}}
+ // If the declaration is in an include-guarded header, make sure we suggest
+ // including that rather than importing a module. In this case, there could
+ // be more than one module, and the module name we picked is almost certainly
+ // wrong.
+ (void)::textual4; // expected-error {{missing '#include "usetextual4.h"'; 'textual4' must be declared before it is used}}
+ (void)::textual5; // expected-error {{missing '#include "usetextual5.h"'; 'textual5' must be declared before it is used}}
// Don't suggest #including a private header.
// FIXME: We could suggest including "useprivate1.h" here, as it's the only
diff --git a/clang/test/Modules/tag-injection.c b/clang/test/Modules/tag-injection.c
index 5bb15477e2e2..727616f5d862 100644
--- a/clang/test/Modules/tag-injection.c
+++ b/clang/test/Modules/tag-injection.c
@@ -14,5 +14,5 @@ void f(struct a *p);
// "compatible types" rule.
void g(struct b *p);
-struct b b; // expected-error {{definition of 'b' must be imported from module 'X.b' before it is required}}
+struct b b; // expected-error {{'b' must be defined before it is used}}
// expected-note at b.h:1 {{here}}
diff --git a/clang/test/Modules/tag-injection.cpp b/clang/test/Modules/tag-injection.cpp
index e55598b06202..dca520e921a1 100644
--- a/clang/test/Modules/tag-injection.cpp
+++ b/clang/test/Modules/tag-injection.cpp
@@ -21,5 +21,5 @@ namespace N {
};
}
-X x; // expected-error {{definition of 'X' must be imported from module 'X.b' before it is required}}
+X x; // expected-error {{'X' must be defined before it is used}}
// expected-note at b.h:1 {{here}}
diff --git a/clang/test/Modules/template-default-args.cpp b/clang/test/Modules/template-default-args.cpp
index c51cb2840884..85b2a18d9e50 100644
--- a/clang/test/Modules/template-default-args.cpp
+++ b/clang/test/Modules/template-default-args.cpp
@@ -37,10 +37,10 @@ extern C<> c;
D<> d;
E<> e;
F<> f;
-G<> g; // expected-error {{default argument of 'G' must be imported from module 'X.A' before it is required}}
-// expected-note at a.h:7 {{default argument declared here}}
-H<> h; // expected-error {{default argument of 'H' must be imported from module 'X.A' before it is required}}
-// expected-note at a.h:8 {{default argument declared here}}
+G<> g; // expected-error {{missing '#include "a.h"'; default argument of 'G' must be defined before it is used}}
+// expected-note at a.h:7 {{default argument declared here is not reachable}}
+H<> h; // expected-error {{missing '#include "a.h"'; default argument of 'H' must be defined before it is used}}
+// expected-note at a.h:8 {{default argument declared here is not reachable}}
I<> i;
L<> *l;
END
diff --git a/clang/test/Modules/undefined-type-fixit1.cpp b/clang/test/Modules/undefined-type-fixit1.cpp
index 3b7345710726..8cb8a3c55de5 100644
--- a/clang/test/Modules/undefined-type-fixit1.cpp
+++ b/clang/test/Modules/undefined-type-fixit1.cpp
@@ -5,8 +5,8 @@
#include "public2.h"
#include "public2sub.h"
-use_this1 client_variable1; // expected-error{{declaration of 'use_this1' must be imported from module 'public1' before it is required}}
+use_this1 client_variable1; // expected-error{{'use_this1' must be declared}}
use_this2 client_variable2;
use_this2sub client_variable2sub;
-// expected-note at Inputs/undefined-type-fixit/public1.h:4 {{previous declaration is here}}
+// expected-note at Inputs/undefined-type-fixit/public1.h:4 {{declaration here is not visible}}
diff --git a/clang/test/Modules/visibility-in-instantiation.cpp b/clang/test/Modules/visibility-in-instantiation.cpp
index 8689758a42ba..81ddfd6baaf3 100644
--- a/clang/test/Modules/visibility-in-instantiation.cpp
+++ b/clang/test/Modules/visibility-in-instantiation.cpp
@@ -47,5 +47,5 @@ void g() {
ST<int>::f(); // expected-error {{must be imported from module 'M.B'}}
foo(X<int>()); // expected-error {{must be imported from module 'M.C'}}
- // expected-note@* 2{{previous declaration is here}}
+ // expected-note@* 2{{declaration here is not visible}}
}
diff --git a/clang/test/SemaCXX/compare-modules-cxx2a.cpp b/clang/test/SemaCXX/compare-modules-cxx2a.cpp
index fa9180024351..afbcce1b0c00 100644
--- a/clang/test/SemaCXX/compare-modules-cxx2a.cpp
+++ b/clang/test/SemaCXX/compare-modules-cxx2a.cpp
@@ -22,12 +22,12 @@ auto va = A() <=> A(); // expected-note {{required here}}
#pragma clang module import compare.other
-// expected-note at std-compare.h:* 2+{{previous definition}}
+// expected-note at std-compare.h:* 2+{{not reachable}}
-void b() { void(0 <=> 0); } // expected-error 1+{{definition of 'strong_ordering' must be imported}}
+void b() { void(0 <=> 0); } // expected-error 1+{{missing '#include "std-compare.h"'; 'strong_ordering' must be defined}}
struct B {
- CC operator<=>(const B&) const = default; // expected-error 1+{{definition of 'strong_ordering' must be imported}}
+ CC operator<=>(const B&) const = default; // expected-error 1+{{missing '#include "std-compare.h"'; 'strong_ordering' must be defined}}
};
auto vb = B() <=> B(); // expected-note {{required here}}
diff --git a/clang/test/SemaCXX/modules-ts.cppm b/clang/test/SemaCXX/modules-ts.cppm
index 1081995c586f..ae15c0825d1a 100644
--- a/clang/test/SemaCXX/modules-ts.cppm
+++ b/clang/test/SemaCXX/modules-ts.cppm
@@ -43,7 +43,7 @@ namespace N {
export struct T {} t;
#elif TEST == 3
int use_a = a; // expected-error {{declaration of 'a' must be imported from module 'foo' before it is required}}
-// expected-note at -13 {{previous}}
+// expected-note at -13 {{declaration here is not visible}}
#undef foo
import foo;
diff --git a/clang/tools/libclang/Indexing.cpp b/clang/tools/libclang/Indexing.cpp
index 05852f3e2bfc..f0303fdcd825 100644
--- a/clang/tools/libclang/Indexing.cpp
+++ b/clang/tools/libclang/Indexing.cpp
@@ -227,7 +227,8 @@ class ParsedSrcLocationsTracker {
}
bool isParsedOnceInclude(const FileEntry *FE) {
- return PP.getHeaderSearchInfo().isFileMultipleIncludeGuarded(FE);
+ return PP.getHeaderSearchInfo().isFileMultipleIncludeGuarded(FE) ||
+ PP.getHeaderSearchInfo().hasFileBeenImported(FE);
}
};
More information about the cfe-commits
mailing list