diff options
author | Richard Smith <richard-llvm@metafoo.co.uk> | 2017-02-23 21:43:43 +0000 |
---|---|---|
committer | Richard Smith <richard-llvm@metafoo.co.uk> | 2017-02-23 21:43:43 +0000 |
commit | a793abf092342591219538bb1cb64060a26f60c0 (patch) | |
tree | 7a873b8e21d794e4a8fa1a1d97849ca0c1a3b9d0 /lib/Sema/SemaTemplateInstantiate.cpp | |
parent | 11e7407389c4b2a6f51cb8983972b591573a4645 (diff) |
Add context note to diagnostics that occur while declaring an implicit special member function.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@296020 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Sema/SemaTemplateInstantiate.cpp')
-rw-r--r-- | lib/Sema/SemaTemplateInstantiate.cpp | 99 |
1 files changed, 65 insertions, 34 deletions
diff --git a/lib/Sema/SemaTemplateInstantiate.cpp b/lib/Sema/SemaTemplateInstantiate.cpp index 7b09b77da3..314dfe3256 100644 --- a/lib/Sema/SemaTemplateInstantiate.cpp +++ b/lib/Sema/SemaTemplateInstantiate.cpp @@ -196,6 +196,7 @@ bool Sema::CodeSynthesisContext::isInstantiationRecord() const { return true; case DefaultTemplateArgumentChecking: + case DeclaringSpecialMember: return false; } @@ -207,8 +208,7 @@ Sema::InstantiatingTemplate::InstantiatingTemplate( SourceLocation PointOfInstantiation, SourceRange InstantiationRange, Decl *Entity, NamedDecl *Template, ArrayRef<TemplateArgument> TemplateArgs, sema::TemplateDeductionInfo *DeductionInfo) - : SemaRef(SemaRef), SavedInNonInstantiationSFINAEContext( - SemaRef.InNonInstantiationSFINAEContext) { + : SemaRef(SemaRef) { // Don't allow further instantiation if a fatal error and an uncompilable // error have occurred. Any diagnostics we might have raised will not be // visible, and we do not need to construct a correct AST. @@ -228,14 +228,12 @@ Sema::InstantiatingTemplate::InstantiatingTemplate( Inst.NumTemplateArgs = TemplateArgs.size(); Inst.DeductionInfo = DeductionInfo; Inst.InstantiationRange = InstantiationRange; + SemaRef.pushCodeSynthesisContext(Inst); + AlreadyInstantiating = !SemaRef.InstantiatingSpecializations .insert(std::make_pair(Inst.Entity->getCanonicalDecl(), Inst.Kind)) .second; - SemaRef.InNonInstantiationSFINAEContext = false; - SemaRef.CodeSynthesisContexts.push_back(Inst); - if (!Inst.isInstantiationRecord()) - ++SemaRef.NonInstantiationEntries; } } @@ -348,38 +346,55 @@ Sema::InstantiatingTemplate::InstantiatingTemplate( PointOfInstantiation, InstantiationRange, Param, Template, TemplateArgs) {} -void Sema::InstantiatingTemplate::Clear() { - if (!Invalid) { - auto &Active = SemaRef.CodeSynthesisContexts.back(); - if (!Active.isInstantiationRecord()) { - assert(SemaRef.NonInstantiationEntries > 0); - --SemaRef.NonInstantiationEntries; - } - SemaRef.InNonInstantiationSFINAEContext - = SavedInNonInstantiationSFINAEContext; - - // Name lookup no longer looks in this template's defining module. - assert(SemaRef.CodeSynthesisContexts.size() >= - SemaRef.CodeSynthesisContextLookupModules.size() && - "forgot to remove a lookup module for a template instantiation"); - if (SemaRef.CodeSynthesisContexts.size() == - SemaRef.CodeSynthesisContextLookupModules.size()) { - if (Module *M = SemaRef.CodeSynthesisContextLookupModules.back()) - SemaRef.LookupModulesCache.erase(M); - SemaRef.CodeSynthesisContextLookupModules.pop_back(); - } +void Sema::pushCodeSynthesisContext(CodeSynthesisContext Ctx) { + Ctx.SavedInNonInstantiationSFINAEContext = InNonInstantiationSFINAEContext; + InNonInstantiationSFINAEContext = false; + + CodeSynthesisContexts.push_back(Ctx); - // If we've left the code synthesis context for the current context stack, - // stop remembering that we've emitted that stack. - if (SemaRef.CodeSynthesisContexts.size() == - SemaRef.LastEmittedCodeSynthesisContextDepth) - SemaRef.LastEmittedCodeSynthesisContextDepth = 0; + if (!Ctx.isInstantiationRecord()) + ++NonInstantiationEntries; +} - if (!AlreadyInstantiating) +void Sema::popCodeSynthesisContext() { + auto &Active = CodeSynthesisContexts.back(); + if (!Active.isInstantiationRecord()) { + assert(NonInstantiationEntries > 0); + --NonInstantiationEntries; + } + + InNonInstantiationSFINAEContext = Active.SavedInNonInstantiationSFINAEContext; + + // Name lookup no longer looks in this template's defining module. + assert(CodeSynthesisContexts.size() >= + CodeSynthesisContextLookupModules.size() && + "forgot to remove a lookup module for a template instantiation"); + if (CodeSynthesisContexts.size() == + CodeSynthesisContextLookupModules.size()) { + if (Module *M = CodeSynthesisContextLookupModules.back()) + LookupModulesCache.erase(M); + CodeSynthesisContextLookupModules.pop_back(); + } + + // If we've left the code synthesis context for the current context stack, + // stop remembering that we've emitted that stack. + if (CodeSynthesisContexts.size() == + LastEmittedCodeSynthesisContextDepth) + LastEmittedCodeSynthesisContextDepth = 0; + + CodeSynthesisContexts.pop_back(); +} + +void Sema::InstantiatingTemplate::Clear() { + if (!Invalid) { + if (!AlreadyInstantiating) { + auto &Active = SemaRef.CodeSynthesisContexts.back(); SemaRef.InstantiatingSpecializations.erase( std::make_pair(Active.Entity, Active.Kind)); + } + + SemaRef.popCodeSynthesisContext(); - SemaRef.CodeSynthesisContexts.pop_back(); Invalid = true; } } @@ -603,6 +618,12 @@ void Sema::PrintInstantiationStack() { << cast<FunctionDecl>(Active->Entity) << Active->InstantiationRange; break; + + case CodeSynthesisContext::DeclaringSpecialMember: + Diags.Report(Active->PointOfInstantiation, + diag::note_in_declaration_of_implicit_special_member) + << cast<CXXRecordDecl>(Active->Entity) << Active->SpecialMember; + break; } } } @@ -617,7 +638,7 @@ Optional<TemplateDeductionInfo *> Sema::isSFINAEContext() const { Active != ActiveEnd; ++Active) { - switch(Active->Kind) { + switch (Active->Kind) { case CodeSynthesisContext::TemplateInstantiation: // An instantiation of an alias template may or may not be a SFINAE // context, depending on what else is on the stack. @@ -643,7 +664,17 @@ Optional<TemplateDeductionInfo *> Sema::isSFINAEContext() const { // or deduced template arguments, so SFINAE applies. assert(Active->DeductionInfo && "Missing deduction info pointer"); return Active->DeductionInfo; + + case CodeSynthesisContext::DeclaringSpecialMember: + // This happens in a context unrelated to template instantiation, so + // there is no SFINAE. + return None; } + + // The inner context was transparent for SFINAE. If it occurred within a + // non-instantiation SFINAE context, then SFINAE applies. + if (Active->SavedInNonInstantiationSFINAEContext) + return Optional<TemplateDeductionInfo *>(nullptr); } return None; |