diff options
author | Douglas Gregor <dgregor@apple.com> | 2010-05-17 17:34:56 +0000 |
---|---|---|
committer | Douglas Gregor <dgregor@apple.com> | 2010-05-17 17:34:56 +0000 |
commit | 6cfacfe54c75baa4d67f1fbdf4f80644b662818e (patch) | |
tree | ff0d6070954b892bbb06d57e48474e0989dff700 /lib/Sema/SemaTemplateInstantiateDecl.cpp | |
parent | e32b9b854e5b92b223c553164d3ecfbf657dbbf2 (diff) |
Determine when the instantiation of a friend function defined inside a
class template conflicts with an existing (non-template)
definition. This is another part of PR6952.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@103948 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Sema/SemaTemplateInstantiateDecl.cpp')
-rw-r--r-- | lib/Sema/SemaTemplateInstantiateDecl.cpp | 25 |
1 files changed, 21 insertions, 4 deletions
diff --git a/lib/Sema/SemaTemplateInstantiateDecl.cpp b/lib/Sema/SemaTemplateInstantiateDecl.cpp index 41c6218664..31284071ff 100644 --- a/lib/Sema/SemaTemplateInstantiateDecl.cpp +++ b/lib/Sema/SemaTemplateInstantiateDecl.cpp @@ -1983,11 +1983,29 @@ void Sema::InstantiateFunctionDefinition(SourceLocation PointOfInstantiation, if (Function->isInvalidDecl()) return; - assert(!Function->getBody() && "Already instantiated!"); - // Never instantiate an explicit specialization. if (Function->getTemplateSpecializationKind() == TSK_ExplicitSpecialization) return; + + const FunctionDecl *Definition = 0; + if (Function->getBody(Definition)) { + // We are trying to instantiate a friend function specialization inside + // a class template, but there is already another (non-template) definition + // of the same function. + if (Definition->getTemplateSpecializationKind() == TSK_Undeclared) { + InstantiatingTemplate Inst(*this, PointOfInstantiation, Function); + if (Inst) + return; + + Diag(Function->getLocation(), diag::err_redefinition) + << Function->getDeclName(); + Diag(Definition->getLocation(), diag::note_previous_definition); + } + + // We have an explicit instantiation (which already occurred) and an + // implicit instantiation. Return without complaint. + return; + } // Find the function body that we'll be substituting. const FunctionDecl *PatternDecl = Function->getTemplateInstantiationPattern(); @@ -2680,8 +2698,7 @@ void Sema::PerformPendingImplicitInstantiations(bool LocalOnly) { Context.getSourceManager(), "instantiating function definition"); - if (!Function->getBody()) - InstantiateFunctionDefinition(/*FIXME:*/Inst.second, Function, true); + InstantiateFunctionDefinition(/*FIXME:*/Inst.second, Function, true); continue; } |