diff options
author | Richard Smith <richard-llvm@metafoo.co.uk> | 2019-04-18 00:56:58 +0000 |
---|---|---|
committer | Richard Smith <richard-llvm@metafoo.co.uk> | 2019-04-18 00:56:58 +0000 |
commit | c2e330a40a66179aa8ee3172b96e0c40dd31593e (patch) | |
tree | 06ffa5cf0dafebe84d4799c8271c80b47a0cba50 /lib/Sema/SemaLookup.cpp | |
parent | e9149d19acaa08b5de55ecbd19348cbb60cdde72 (diff) | |
download | clang-c2e330a40a66179aa8ee3172b96e0c40dd31593e.tar.gz |
[c++2a] Improve diagnostic for use of declaration from another TU's
global module fragment.
We know that the declaration in question should have been introduced by
a '#include', so try to figure out which one and suggest it. Don't
suggest importing the global module fragment itself!
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@358631 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Sema/SemaLookup.cpp')
-rw-r--r-- | lib/Sema/SemaLookup.cpp | 70 |
1 files changed, 49 insertions, 21 deletions
diff --git a/lib/Sema/SemaLookup.cpp b/lib/Sema/SemaLookup.cpp index c5d8c2f50d..874e561130 100644 --- a/lib/Sema/SemaLookup.cpp +++ b/lib/Sema/SemaLookup.cpp @@ -5073,7 +5073,7 @@ void Sema::diagnoseMissingImport(SourceLocation Loc, NamedDecl *Decl, auto Merged = Context.getModulesWithMergedDefinition(Def); OwningModules.insert(OwningModules.end(), Merged.begin(), Merged.end()); - diagnoseMissingImport(Loc, Decl, Decl->getLocation(), OwningModules, MIK, + diagnoseMissingImport(Loc, Def, Def->getLocation(), OwningModules, MIK, Recover); } @@ -5093,12 +5093,58 @@ void Sema::diagnoseMissingImport(SourceLocation UseLoc, NamedDecl *Decl, MissingImportKind MIK, bool Recover) { 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); + }; + // Weed out duplicates from module list. llvm::SmallVector<Module*, 8> UniqueModules; llvm::SmallDenseSet<Module*, 8> UniqueModuleSet; - for (auto *M : Modules) + for (auto *M : Modules) { + if (M->Kind == Module::GlobalModuleFragment) + continue; if (UniqueModuleSet.insert(M).second) UniqueModules.push_back(M); + } + + if (UniqueModules.empty()) { + // All candidates were global module fragments. Try to suggest a #include. + const FileEntry *E = + PP.getModuleHeaderToIncludeForDiagnostics(UseLoc, Modules[0], DeclLoc); + // 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) : ""); + // 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(); + if (Recover) + createImplicitModuleImportForErrorRecovery(UseLoc, Modules[0]); + return; + } + Modules = UniqueModules; if (Modules.size() > 1) { @@ -5131,25 +5177,7 @@ void Sema::diagnoseMissingImport(SourceLocation UseLoc, NamedDecl *Decl, << (int)MIK << Decl << Modules[0]->getFullModuleName(); } - 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); + NotePrevious(); // Try to recover by implicitly importing this module. if (Recover) |