miyuki updated this revision to Diff 128234.
miyuki added a comment.
Factored out template language linkage check into a separate function
https://reviews.llvm.org/D41179
Files:
lib/Sema/SemaTemplate.cpp
test/SemaTemplate/class-template-spec.cpp
test/SemaTemplate/function-template-specialization.cpp
Index: test/SemaTemplate/function-template-specialization.cpp
===================================================================
--- test/SemaTemplate/function-template-specialization.cpp
+++ test/SemaTemplate/function-template-specialization.cpp
@@ -56,3 +56,8 @@
template<>
static void Bar(const long& input) {} // expected-error{{explicit
specialization of 'Bar' in class scope}}
};
+
+template<typename T> void f3(T) {}
+extern "C" { // expected-note {{extern "C" language linkage specification
begins here}}
+ template<> void f3(int) {} // expected-error{{templates must have C++
linkage}}
+}
Index: test/SemaTemplate/class-template-spec.cpp
===================================================================
--- test/SemaTemplate/class-template-spec.cpp
+++ test/SemaTemplate/class-template-spec.cpp
@@ -235,3 +235,9 @@
> struct S;
template<typename T> struct S<T> {}; // expected-error {{non-type template
argument specializes a template parameter with dependent type 'T'}}
}
+
+template<typename T> struct C {};
+extern "C" { // expected-note 2{{extern "C" language linkage specification
begins here}}
+ template<typename T> struct C<T*> {}; // expected-error{{templates must have
C++ linkage}}
+ template<> struct C<int> {}; // expected-error{{templates must have C++
linkage}}
+}
Index: lib/Sema/SemaTemplate.cpp
===================================================================
--- lib/Sema/SemaTemplate.cpp
+++ lib/Sema/SemaTemplate.cpp
@@ -6953,6 +6953,21 @@
return true;
}
+/// \brief Check whether a template is declared with "C" language linkage.
+///
+/// If a template or a template specialization is declared with "C" language
+/// linkage, issues a diagnostic and returns true. Otherwise, returns false.
+static bool
+CheckTemplateLanguageLinkage(Sema &S, DeclContext *Ctx, SourceRange Rng) {
+ if (Ctx && Ctx->isExternCContext()) {
+ S.Diag(Rng.getBegin(), diag::err_template_linkage) << Rng;
+ if (const LinkageSpecDecl *LSD = Ctx->getExternCContext())
+ S.Diag(LSD->getExternLoc(), diag::note_extern_c_begins_here);
+ return true;
+ }
+ return false;
+}
+
/// \brief Check whether a template can be declared within this scope.
///
/// If the template declaration is valid in this scope, returns
@@ -6970,13 +6985,10 @@
// C++ [temp]p4:
// A template [...] shall not have C linkage.
DeclContext *Ctx = S->getEntity();
- if (Ctx && Ctx->isExternCContext()) {
- Diag(TemplateParams->getTemplateLoc(), diag::err_template_linkage)
- << TemplateParams->getSourceRange();
- if (const LinkageSpecDecl *LSD = Ctx->getExternCContext())
- Diag(LSD->getExternLoc(), diag::note_extern_c_begins_here);
+ if (CheckTemplateLanguageLinkage(*this, Ctx,
+ TemplateParams->getSourceRange()))
return true;
- }
+
Ctx = Ctx->getRedeclContext();
// C++ [temp]p2:
@@ -7071,6 +7083,12 @@
return true;
}
+ // C++ [temp]p6:
+ // A template, a template explicit specialization, and a class template
+ // partial specialization shall not have C linkage.
+ if (CheckTemplateLanguageLinkage(S, S.CurContext, Loc))
+ return true;
+
// C++ [temp.expl.spec]p2:
// An explicit specialization shall be declared in the namespace
// of which the template is a member, or, for member templates, in
Index: test/SemaTemplate/function-template-specialization.cpp
===================================================================
--- test/SemaTemplate/function-template-specialization.cpp
+++ test/SemaTemplate/function-template-specialization.cpp
@@ -56,3 +56,8 @@
template<>
static void Bar(const long& input) {} // expected-error{{explicit specialization of 'Bar' in class scope}}
};
+
+template<typename T> void f3(T) {}
+extern "C" { // expected-note {{extern "C" language linkage specification begins here}}
+ template<> void f3(int) {} // expected-error{{templates must have C++ linkage}}
+}
Index: test/SemaTemplate/class-template-spec.cpp
===================================================================
--- test/SemaTemplate/class-template-spec.cpp
+++ test/SemaTemplate/class-template-spec.cpp
@@ -235,3 +235,9 @@
> struct S;
template<typename T> struct S<T> {}; // expected-error {{non-type template argument specializes a template parameter with dependent type 'T'}}
}
+
+template<typename T> struct C {};
+extern "C" { // expected-note 2{{extern "C" language linkage specification begins here}}
+ template<typename T> struct C<T*> {}; // expected-error{{templates must have C++ linkage}}
+ template<> struct C<int> {}; // expected-error{{templates must have C++ linkage}}
+}
Index: lib/Sema/SemaTemplate.cpp
===================================================================
--- lib/Sema/SemaTemplate.cpp
+++ lib/Sema/SemaTemplate.cpp
@@ -6953,6 +6953,21 @@
return true;
}
+/// \brief Check whether a template is declared with "C" language linkage.
+///
+/// If a template or a template specialization is declared with "C" language
+/// linkage, issues a diagnostic and returns true. Otherwise, returns false.
+static bool
+CheckTemplateLanguageLinkage(Sema &S, DeclContext *Ctx, SourceRange Rng) {
+ if (Ctx && Ctx->isExternCContext()) {
+ S.Diag(Rng.getBegin(), diag::err_template_linkage) << Rng;
+ if (const LinkageSpecDecl *LSD = Ctx->getExternCContext())
+ S.Diag(LSD->getExternLoc(), diag::note_extern_c_begins_here);
+ return true;
+ }
+ return false;
+}
+
/// \brief Check whether a template can be declared within this scope.
///
/// If the template declaration is valid in this scope, returns
@@ -6970,13 +6985,10 @@
// C++ [temp]p4:
// A template [...] shall not have C linkage.
DeclContext *Ctx = S->getEntity();
- if (Ctx && Ctx->isExternCContext()) {
- Diag(TemplateParams->getTemplateLoc(), diag::err_template_linkage)
- << TemplateParams->getSourceRange();
- if (const LinkageSpecDecl *LSD = Ctx->getExternCContext())
- Diag(LSD->getExternLoc(), diag::note_extern_c_begins_here);
+ if (CheckTemplateLanguageLinkage(*this, Ctx,
+ TemplateParams->getSourceRange()))
return true;
- }
+
Ctx = Ctx->getRedeclContext();
// C++ [temp]p2:
@@ -7071,6 +7083,12 @@
return true;
}
+ // C++ [temp]p6:
+ // A template, a template explicit specialization, and a class template
+ // partial specialization shall not have C linkage.
+ if (CheckTemplateLanguageLinkage(S, S.CurContext, Loc))
+ return true;
+
// C++ [temp.expl.spec]p2:
// An explicit specialization shall be declared in the namespace
// of which the template is a member, or, for member templates, in
_______________________________________________
cfe-commits mailing list
[email protected]
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits