diff options
author | Douglas Gregor <dgregor@apple.com> | 2010-05-17 17:57:54 +0000 |
---|---|---|
committer | Douglas Gregor <dgregor@apple.com> | 2010-05-17 17:57:54 +0000 |
commit | fd7224fee04c801dd4b7a38f6acc7310e921aeb4 (patch) | |
tree | 54127b4367e0009bfed6ebc893602652ef1328ec /clang/lib/Sema/SemaTemplateInstantiateDecl.cpp | |
parent | 9b4a824217f1fe23f83045afe7521acb791bc2d0 (diff) | |
download | bcm5719-llvm-fd7224fee04c801dd4b7a38f6acc7310e921aeb4.tar.gz bcm5719-llvm-fd7224fee04c801dd4b7a38f6acc7310e921aeb4.zip |
Diagnose a redefinition error when there are two instantiations of friend
functions defined inside a class template. Fixes PR6952, the last
Boost.Units failure.
llvm-svn: 103952
Diffstat (limited to 'clang/lib/Sema/SemaTemplateInstantiateDecl.cpp')
-rw-r--r-- | clang/lib/Sema/SemaTemplateInstantiateDecl.cpp | 30 |
1 files changed, 29 insertions, 1 deletions
diff --git a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp index 31284071ff6..1280c0cb88e 100644 --- a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp +++ b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp @@ -2000,7 +2000,8 @@ void Sema::InstantiateFunctionDefinition(SourceLocation PointOfInstantiation, Diag(Function->getLocation(), diag::err_redefinition) << Function->getDeclName(); Diag(Definition->getLocation(), diag::note_previous_definition); - } + Function->setInvalidDecl(); + } // We have an explicit instantiation (which already occurred) and an // implicit instantiation. Return without complaint. @@ -2027,11 +2028,38 @@ void Sema::InstantiateFunctionDefinition(SourceLocation PointOfInstantiation, if (PatternDecl) Diag(PatternDecl->getLocation(), diag::note_explicit_instantiation_here); + Function->setInvalidDecl(); } return; } + // If this is an instantiation of friend function defined within a class + // template or class template specialization or member class thereof, + // determine whether there were multiple instantiations of its lexical class. + if (PatternDecl->getFriendObjectKind() != Decl::FOK_None) { + for (FunctionDecl::redecl_iterator R = Function->redecls_begin(), + REnd = Function->redecls_end(); + R != REnd; ++R) { + if (*R != Function && + ((*R)->getFriendObjectKind() != Decl::FOK_None)) { + if (const FunctionDecl *RPattern + = (*R)->getTemplateInstantiationPattern()) + if (RPattern->getBody(RPattern)) { + InstantiatingTemplate Inst(*this, PointOfInstantiation, Function); + if (Inst) + return; + + Diag(Function->getLocation(), diag::err_redefinition) + << Function->getDeclName(); + Diag((*R)->getLocation(), diag::note_previous_definition); + Function->setInvalidDecl(); + return; + } + } + } + } + // C++0x [temp.explicit]p9: // Except for inline functions, other explicit instantiation declarations // have the effect of suppressing the implicit instantiation of the entity |