r237612 - [modules] Support for merging a parsed class template specialization definition into an imported but hidden definition.
Richard Smith
richard-llvm at metafoo.co.uk
Mon May 18 13:36:47 PDT 2015
Author: rsmith
Date: Mon May 18 15:36:47 2015
New Revision: 237612
URL: http://llvm.org/viewvc/llvm-project?rev=237612&view=rev
Log:
[modules] Support for merging a parsed class template specialization definition into an imported but hidden definition.
Modified:
cfe/trunk/include/clang/Sema/Sema.h
cfe/trunk/lib/Parse/ParseDeclCXX.cpp
cfe/trunk/lib/Sema/SemaTemplate.cpp
cfe/trunk/test/Modules/Inputs/submodules-merge-defs/defs.h
Modified: cfe/trunk/include/clang/Sema/Sema.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/Sema.h?rev=237612&r1=237611&r2=237612&view=diff
==============================================================================
--- cfe/trunk/include/clang/Sema/Sema.h (original)
+++ cfe/trunk/include/clang/Sema/Sema.h Mon May 18 15:36:47 2015
@@ -5509,7 +5509,8 @@ public:
SourceLocation ModulePrivateLoc,
TemplateIdAnnotation &TemplateId,
AttributeList *Attr,
- MultiTemplateParamsArg TemplateParameterLists);
+ MultiTemplateParamsArg TemplateParameterLists,
+ SkipBodyInfo *SkipBody = nullptr);
Decl *ActOnTemplateDeclarator(Scope *S,
MultiTemplateParamsArg TemplateParameterLists,
Modified: cfe/trunk/lib/Parse/ParseDeclCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseDeclCXX.cpp?rev=237612&r1=237611&r2=237612&view=diff
==============================================================================
--- cfe/trunk/lib/Parse/ParseDeclCXX.cpp (original)
+++ cfe/trunk/lib/Parse/ParseDeclCXX.cpp Mon May 18 15:36:47 2015
@@ -1640,7 +1640,8 @@ void Parser::ParseClassSpecifier(tok::To
*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) {
Modified: cfe/trunk/lib/Sema/SemaTemplate.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaTemplate.cpp?rev=237612&r1=237611&r2=237612&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaTemplate.cpp (original)
+++ cfe/trunk/lib/Sema/SemaTemplate.cpp Mon May 18 15:36:47 2015
@@ -6052,7 +6052,9 @@ Sema::ActOnClassTemplateSpecialization(S
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(S
// 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;
Modified: cfe/trunk/test/Modules/Inputs/submodules-merge-defs/defs.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Modules/Inputs/submodules-merge-defs/defs.h?rev=237612&r1=237611&r2=237612&view=diff
==============================================================================
--- cfe/trunk/test/Modules/Inputs/submodules-merge-defs/defs.h (original)
+++ cfe/trunk/test/Modules/Inputs/submodules-merge-defs/defs.h Mon May 18 15:36:47 2015
@@ -29,6 +29,11 @@ template<typename T> struct F {
};
template<typename T> int F<T>::f() { return 0; }
template<typename T> template<typename U> int F<T>::g() { return 0; }
+template<> template<typename U> int F<char>::g() { return 0; }
+template<> struct F<void> { int h(); };
+inline int F<void>::h() { return 0; }
+template<typename T> struct F<T *> { int i(); };
+template<typename T> int F<T*>::i() { return 0; }
namespace G {
enum A { a, b, c, d, e };
More information about the cfe-commits
mailing list