]> granicus.if.org Git - clang/commitdiff
[modules] Support for merging a parsed class template specialization definition into...
authorRichard Smith <richard-llvm@metafoo.co.uk>
Mon, 18 May 2015 20:36:47 +0000 (20:36 +0000)
committerRichard Smith <richard-llvm@metafoo.co.uk>
Mon, 18 May 2015 20:36:47 +0000 (20:36 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@237612 91177308-0d34-0410-b5e6-96231b3b80d8

include/clang/Sema/Sema.h
lib/Parse/ParseDeclCXX.cpp
lib/Sema/SemaTemplate.cpp
test/Modules/Inputs/submodules-merge-defs/defs.h

index 42d6265678820ed5e5dc38ddfb4dccb3d7c93588..a7020589e85b00256689b3679471029ef6bbb066 100644 (file)
@@ -5509,7 +5509,8 @@ public:
                                    SourceLocation ModulePrivateLoc,
                                    TemplateIdAnnotation &TemplateId,
                                    AttributeList *Attr,
-                                 MultiTemplateParamsArg TemplateParameterLists);
+                                 MultiTemplateParamsArg TemplateParameterLists,
+                                   SkipBodyInfo *SkipBody = nullptr);
 
   Decl *ActOnTemplateDeclarator(Scope *S,
                                 MultiTemplateParamsArg TemplateParameterLists,
index bb7ae63764a78e4e8b3be542d4b68f6620ea1da1..07fd4742cd53a80d6a9ad5a03a063c50fab93101 100644 (file)
@@ -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) {
index 687e6111f2d66c572578f1e405c4c45875732708..5319836c249d3cc109d460e560b1902a40e81c5c 100644 (file)
@@ -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;
index ccf1398797c59b062f364b8bd61c68b969c58648..ffd996af1849ad4e009652a1fba9305106d21149 100644 (file)
@@ -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 };