diff options
author | dim <dim@FreeBSD.org> | 2015-06-21 14:00:56 +0000 |
---|---|---|
committer | dim <dim@FreeBSD.org> | 2015-06-21 14:00:56 +0000 |
commit | 9dd834653b811ad20382e98a87dff824980c9916 (patch) | |
tree | a764184c2fc9486979b074250b013a0937ee64e5 /lib/Sema/SemaLookup.cpp | |
parent | bb9760db9b86e93a638ed430d0a14785f7ff9064 (diff) | |
download | FreeBSD-src-9dd834653b811ad20382e98a87dff824980c9916.zip FreeBSD-src-9dd834653b811ad20382e98a87dff824980c9916.tar.gz |
Vendor import of clang trunk r240225:
https://llvm.org/svn/llvm-project/cfe/trunk@240225
Diffstat (limited to 'lib/Sema/SemaLookup.cpp')
-rw-r--r-- | lib/Sema/SemaLookup.cpp | 133 |
1 files changed, 116 insertions, 17 deletions
diff --git a/lib/Sema/SemaLookup.cpp b/lib/Sema/SemaLookup.cpp index d0a55b5..3fd1f21 100644 --- a/lib/Sema/SemaLookup.cpp +++ b/lib/Sema/SemaLookup.cpp @@ -1233,6 +1233,12 @@ void Sema::makeMergedDefinitionVisible(NamedDecl *ND, SourceLocation Loc) { else // We're not building a module; just make the definition visible. ND->setHidden(false); + + // If ND is a template declaration, make the template parameters + // visible too. They're not (necessarily) within a mergeable DeclContext. + if (auto *TD = dyn_cast<TemplateDecl>(ND)) + for (auto *Param : *TD->getTemplateParameters()) + makeMergedDefinitionVisible(Param, Loc); } /// \brief Find the module in which the given declaration was defined. @@ -1282,6 +1288,41 @@ bool Sema::hasVisibleMergedDefinition(NamedDecl *Def) { return false; } +template<typename ParmDecl> +static bool +hasVisibleDefaultArgument(Sema &S, const ParmDecl *D, + llvm::SmallVectorImpl<Module *> *Modules) { + if (!D->hasDefaultArgument()) + return false; + + while (D) { + auto &DefaultArg = D->getDefaultArgStorage(); + if (!DefaultArg.isInherited() && S.isVisible(D)) + return true; + + if (!DefaultArg.isInherited() && Modules) { + auto *NonConstD = const_cast<ParmDecl*>(D); + Modules->push_back(S.getOwningModule(NonConstD)); + const auto &Merged = S.Context.getModulesWithMergedDefinition(NonConstD); + Modules->insert(Modules->end(), Merged.begin(), Merged.end()); + } + + // If there was a previous default argument, maybe its parameter is visible. + D = DefaultArg.getInheritedFrom(); + } + return false; +} + +bool Sema::hasVisibleDefaultArgument(const NamedDecl *D, + llvm::SmallVectorImpl<Module *> *Modules) { + if (auto *P = dyn_cast<TemplateTypeParmDecl>(D)) + return ::hasVisibleDefaultArgument(*this, P, Modules); + if (auto *P = dyn_cast<NonTypeTemplateParmDecl>(D)) + return ::hasVisibleDefaultArgument(*this, P, Modules); + return ::hasVisibleDefaultArgument(*this, cast<TemplateTemplateParmDecl>(D), + Modules); +} + /// \brief Determine whether a declaration is visible to name lookup. /// /// This routine determines whether the declaration D is visible in the current @@ -3006,6 +3047,9 @@ void Sema::ArgumentDependentLookup(DeclarationName Name, SourceLocation Loc, if (!isa<FunctionDecl>(D) && !isa<FunctionTemplateDecl>(D)) continue; + if (!isVisible(D) && !(D = findAcceptableDecl(*this, D))) + continue; + Result.insert(D); } } @@ -4632,6 +4676,76 @@ 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"); + + llvm::SmallVector<Module*, 8> OwningModules; + OwningModules.push_back(Owner); + auto Merged = Context.getModulesWithMergedDefinition(Decl); + OwningModules.insert(OwningModules.end(), Merged.begin(), Merged.end()); + + diagnoseMissingImport(Loc, Decl, Decl->getLocation(), OwningModules, + NeedDefinition ? MissingImportKind::Definition + : MissingImportKind::Declaration, + Recover); +} + +void Sema::diagnoseMissingImport(SourceLocation UseLoc, NamedDecl *Decl, + SourceLocation DeclLoc, + ArrayRef<Module *> Modules, + MissingImportKind MIK, bool Recover) { + assert(!Modules.empty()); + + if (Modules.size() > 1) { + std::string ModuleList; + unsigned N = 0; + for (Module *M : Modules) { + ModuleList += "\n "; + if (++N == 5 && N != Modules.size()) { + ModuleList += "[...]"; + break; + } + ModuleList += M->getFullModuleName(); + } + + Diag(UseLoc, diag::err_module_unimported_use_multiple) + << (int)MIK << Decl << ModuleList; + } else { + Diag(UseLoc, diag::err_module_unimported_use) + << (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; + } + Diag(DeclLoc, DiagID); + + // Try to recover by implicitly importing this module. + if (Recover) + createImplicitModuleImportForErrorRecovery(UseLoc, Modules[0]); +} + /// \brief Diagnose a successfully-corrected typo. Separated from the correction /// itself to allow external validation of the result, etc. /// @@ -4658,23 +4772,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; } |