summaryrefslogtreecommitdiffstats
path: root/lib/Sema/SemaLookup.cpp
diff options
context:
space:
mode:
authordim <dim@FreeBSD.org>2015-06-21 14:00:56 +0000
committerdim <dim@FreeBSD.org>2015-06-21 14:00:56 +0000
commit9dd834653b811ad20382e98a87dff824980c9916 (patch)
treea764184c2fc9486979b074250b013a0937ee64e5 /lib/Sema/SemaLookup.cpp
parentbb9760db9b86e93a638ed430d0a14785f7ff9064 (diff)
downloadFreeBSD-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.cpp133
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;
}
OpenPOWER on IntegriCloud