summaryrefslogtreecommitdiffstats
path: root/clang/lib/Sema/SemaTemplate.cpp
diff options
context:
space:
mode:
authorRichard Smith <richard-llvm@metafoo.co.uk>2015-03-27 00:41:57 +0000
committerRichard Smith <richard-llvm@metafoo.co.uk>2015-03-27 00:41:57 +0000
commitbe3980b73c6c48832ed3ffc6760f0080e0217cbb (patch)
tree8bbffa80b54fe03c222cadec48ae1df45fc1862f /clang/lib/Sema/SemaTemplate.cpp
parent3cd2cabf5076d138a6685b9f99c559fa0402adde (diff)
downloadbcm5719-llvm-be3980b73c6c48832ed3ffc6760f0080e0217cbb.tar.gz
bcm5719-llvm-be3980b73c6c48832ed3ffc6760f0080e0217cbb.zip
[modules] Handle defining a class template on top of an existing imported-but-not-visible definition.
llvm-svn: 233341
Diffstat (limited to 'clang/lib/Sema/SemaTemplate.cpp')
-rw-r--r--clang/lib/Sema/SemaTemplate.cpp21
1 files changed, 20 insertions, 1 deletions
diff --git a/clang/lib/Sema/SemaTemplate.cpp b/clang/lib/Sema/SemaTemplate.cpp
index 805709dab80..c642c0599b5 100644
--- a/clang/lib/Sema/SemaTemplate.cpp
+++ b/clang/lib/Sema/SemaTemplate.cpp
@@ -12,6 +12,7 @@
#include "TreeTransform.h"
#include "clang/AST/ASTConsumer.h"
#include "clang/AST/ASTContext.h"
+#include "clang/AST/ASTMutationListener.h"
#include "clang/AST/DeclFriend.h"
#include "clang/AST/DeclTemplate.h"
#include "clang/AST/Expr.h"
@@ -836,7 +837,8 @@ Sema::CheckClassTemplate(Scope *S, unsigned TagSpec, TagUseKind TUK,
AccessSpecifier AS, SourceLocation ModulePrivateLoc,
SourceLocation FriendLoc,
unsigned NumOuterTemplateParamLists,
- TemplateParameterList** OuterTemplateParamLists) {
+ TemplateParameterList** OuterTemplateParamLists,
+ bool *SkipBody) {
assert(TemplateParams && TemplateParams->size() > 0 &&
"No template parameters");
assert(TUK != TUK_Reference && "Can only declare or define class templates");
@@ -993,6 +995,23 @@ Sema::CheckClassTemplate(Scope *S, unsigned TagSpec, TagUseKind TUK,
// Check for redefinition of this class template.
if (TUK == TUK_Definition) {
if (TagDecl *Def = PrevRecordDecl->getDefinition()) {
+ // If we have a prior definition that is not visible, treat this as
+ // simply making that previous definition visible.
+ NamedDecl *Hidden = nullptr;
+ if (SkipBody && !hasVisibleDefinition(Def, &Hidden)) {
+ *SkipBody = true;
+ auto *Tmpl = cast<CXXRecordDecl>(Hidden)->getDescribedClassTemplate();
+ assert(Tmpl && "original definition of a class template is not a "
+ "class template?");
+ if (auto *Listener = getASTMutationListener()) {
+ Listener->RedefinedHiddenDefinition(Hidden, KWLoc);
+ Listener->RedefinedHiddenDefinition(Tmpl, KWLoc);
+ }
+ Hidden->setHidden(false);
+ Tmpl->setHidden(false);
+ return Def;
+ }
+
Diag(NameLoc, diag::err_redefinition) << Name;
Diag(Def->getLocation(), diag::note_previous_definition);
// FIXME: Would it make sense to try to "forget" the previous
OpenPOWER on IntegriCloud