diff options
author | Richard Smith <richard-llvm@metafoo.co.uk> | 2015-06-15 20:15:48 +0000 |
---|---|---|
committer | Richard Smith <richard-llvm@metafoo.co.uk> | 2015-06-15 20:15:48 +0000 |
commit | f2b1eb9eb2fb25f5263a2280646cc154b6532602 (patch) | |
tree | bebed0f29ab3f166fa3d33adc555f411eac43f31 /clang/lib/Sema/SemaLookup.cpp | |
parent | 4223a1f81158534ce497768c491357086f389ff5 (diff) | |
download | bcm5719-llvm-f2b1eb9eb2fb25f5263a2280646cc154b6532602.tar.gz bcm5719-llvm-f2b1eb9eb2fb25f5263a2280646cc154b6532602.zip |
[modules] Better support for redefinitions of an entity from the same module.
Support this across module save/reload and extend the 'missing import'
diagnostics with a list of providing modules.
llvm-svn: 239750
Diffstat (limited to 'clang/lib/Sema/SemaLookup.cpp')
-rw-r--r-- | clang/lib/Sema/SemaLookup.cpp | 63 |
1 files changed, 46 insertions, 17 deletions
diff --git a/clang/lib/Sema/SemaLookup.cpp b/clang/lib/Sema/SemaLookup.cpp index 202f027f6f8..b5ef3a42d17 100644 --- a/clang/lib/Sema/SemaLookup.cpp +++ b/clang/lib/Sema/SemaLookup.cpp @@ -4661,6 +4661,50 @@ static NamedDecl *getDefinitionToImport(NamedDecl *D) { return nullptr; } +void Sema::diagnoseMissingImport(SourceLocation Loc, NamedDecl *Decl, + bool NeedDefinition, bool Recover) { + assert(!isVisible(Decl) && "missing import for non-hidden decl?"); + + // Suggest importing a module providing the definition of this entity, if + // possible. + NamedDecl *Def = getDefinitionToImport(Decl); + if (!Def) + Def = Decl; + + // FIXME: Add a Fix-It that imports the corresponding module or includes + // the header. + Module *Owner = getOwningModule(Decl); + assert(Owner && "definition of hidden declaration is not in a module"); + + auto Merged = Context.getModulesWithMergedDefinition(Decl); + if (!Merged.empty()) { + std::string ModuleList; + ModuleList += "\n "; + ModuleList += Owner->getFullModuleName(); + unsigned N = 0; + for (Module *M : Merged) { + ModuleList += "\n "; + if (++N == 5 && Merged.size() != N) { + ModuleList += "[...]"; + break; + } + ModuleList += M->getFullModuleName(); + } + + Diag(Loc, diag::err_module_private_declaration_multiple) + << NeedDefinition << Decl << ModuleList; + } else { + Diag(Loc, diag::err_module_private_declaration) + << NeedDefinition << Decl << Owner->getFullModuleName(); + } + Diag(Decl->getLocation(), NeedDefinition ? diag::note_previous_definition + : diag::note_previous_declaration); + + // Try to recover by implicitly importing this module. + if (Recover) + createImplicitModuleImportForErrorRecovery(Loc, Owner); +} + /// \brief Diagnose a successfully-corrected typo. Separated from the correction /// itself to allow external validation of the result, etc. /// @@ -4687,23 +4731,8 @@ void Sema::diagnoseTypo(const TypoCorrection &Correction, NamedDecl *Decl = Correction.getCorrectionDecl(); assert(Decl && "import required but no declaration to import"); - // Suggest importing a module providing the definition of this entity, if - // possible. - NamedDecl *Def = getDefinitionToImport(Decl); - if (!Def) - Def = Decl; - Module *Owner = getOwningModule(Def); - assert(Owner && "definition of hidden declaration is not in a module"); - - Diag(Correction.getCorrectionRange().getBegin(), - diag::err_module_private_declaration) - << Def << Owner->getFullModuleName(); - Diag(Def->getLocation(), diag::note_previous_declaration); - - // Recover by implicitly importing this module. - if (ErrorRecovery) - createImplicitModuleImportForErrorRecovery( - Correction.getCorrectionRange().getBegin(), Owner); + diagnoseMissingImport(Correction.getCorrectionRange().getBegin(), Decl, + /*NeedDefinition*/ false, ErrorRecovery); return; } |