diff options
author | Richard Smith <richard-llvm@metafoo.co.uk> | 2015-03-27 00:41:57 +0000 |
---|---|---|
committer | Richard Smith <richard-llvm@metafoo.co.uk> | 2015-03-27 00:41:57 +0000 |
commit | be3980b73c6c48832ed3ffc6760f0080e0217cbb (patch) | |
tree | 8bbffa80b54fe03c222cadec48ae1df45fc1862f /clang/lib/Sema/SemaTemplate.cpp | |
parent | 3cd2cabf5076d138a6685b9f99c559fa0402adde (diff) | |
download | bcm5719-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.cpp | 21 |
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 |