From c2b4714da370f5ba52d0e0662152a90af87ea0cb Mon Sep 17 00:00:00 2001 From: Richard Smith Date: Mon, 18 May 2015 20:36:47 +0000 Subject: [PATCH] [modules] Support for merging a parsed class template specialization definition into an imported but hidden definition. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@237612 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/clang/Sema/Sema.h | 3 ++- lib/Parse/ParseDeclCXX.cpp | 3 ++- lib/Sema/SemaTemplate.cpp | 13 +++++++++++-- test/Modules/Inputs/submodules-merge-defs/defs.h | 5 +++++ 4 files changed, 20 insertions(+), 4 deletions(-) diff --git a/include/clang/Sema/Sema.h b/include/clang/Sema/Sema.h index 42d6265678..a7020589e8 100644 --- a/include/clang/Sema/Sema.h +++ b/include/clang/Sema/Sema.h @@ -5509,7 +5509,8 @@ public: SourceLocation ModulePrivateLoc, TemplateIdAnnotation &TemplateId, AttributeList *Attr, - MultiTemplateParamsArg TemplateParameterLists); + MultiTemplateParamsArg TemplateParameterLists, + SkipBodyInfo *SkipBody = nullptr); Decl *ActOnTemplateDeclarator(Scope *S, MultiTemplateParamsArg TemplateParameterLists, diff --git a/lib/Parse/ParseDeclCXX.cpp b/lib/Parse/ParseDeclCXX.cpp index bb7ae63764..07fd4742cd 100644 --- a/lib/Parse/ParseDeclCXX.cpp +++ b/lib/Parse/ParseDeclCXX.cpp @@ -1640,7 +1640,8 @@ void Parser::ParseClassSpecifier(tok::TokenKind TagTokKind, *TemplateId, attrs.getList(), MultiTemplateParamsArg(TemplateParams ? &(*TemplateParams)[0] : nullptr, - TemplateParams ? TemplateParams->size() : 0)); + TemplateParams ? TemplateParams->size() : 0), + &SkipBody); } } else if (TemplateInfo.Kind == ParsedTemplateInfo::ExplicitInstantiation && TUK == Sema::TUK_Declaration) { diff --git a/lib/Sema/SemaTemplate.cpp b/lib/Sema/SemaTemplate.cpp index 687e6111f2..5319836c24 100644 --- a/lib/Sema/SemaTemplate.cpp +++ b/lib/Sema/SemaTemplate.cpp @@ -6052,7 +6052,9 @@ Sema::ActOnClassTemplateSpecialization(Scope *S, unsigned TagSpec, SourceLocation ModulePrivateLoc, TemplateIdAnnotation &TemplateId, AttributeList *Attr, - MultiTemplateParamsArg TemplateParameterLists) { + MultiTemplateParamsArg + TemplateParameterLists, + SkipBodyInfo *SkipBody) { assert(TUK != TUK_Reference && "References are not specializations"); CXXScopeSpec &SS = TemplateId.SS; @@ -6363,7 +6365,14 @@ Sema::ActOnClassTemplateSpecialization(Scope *S, unsigned TagSpec, // Check that this isn't a redefinition of this specialization. if (TUK == TUK_Definition) { - if (RecordDecl *Def = Specialization->getDefinition()) { + RecordDecl *Def = Specialization->getDefinition(); + NamedDecl *Hidden = nullptr; + if (Def && SkipBody && !hasVisibleDefinition(Def, &Hidden)) { + SkipBody->ShouldSkip = true; + makeMergedDefinitionVisible(Hidden, KWLoc); + // From here on out, treat this as just a redeclaration. + TUK = TUK_Declaration; + } else if (Def) { SourceRange Range(TemplateNameLoc, RAngleLoc); Diag(TemplateNameLoc, diag::err_redefinition) << Context.getTypeDeclType(Specialization) << Range; diff --git a/test/Modules/Inputs/submodules-merge-defs/defs.h b/test/Modules/Inputs/submodules-merge-defs/defs.h index ccf1398797..ffd996af18 100644 --- a/test/Modules/Inputs/submodules-merge-defs/defs.h +++ b/test/Modules/Inputs/submodules-merge-defs/defs.h @@ -29,6 +29,11 @@ template struct F { }; template int F::f() { return 0; } template template int F::g() { return 0; } +template<> template int F::g() { return 0; } +template<> struct F { int h(); }; +inline int F::h() { return 0; } +template struct F { int i(); }; +template int F::i() { return 0; } namespace G { enum A { a, b, c, d, e }; -- 2.40.0