aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/clang/Basic/DiagnosticParseKinds.td5
-rw-r--r--lib/Parse/Parser.cpp3
-rw-r--r--test/CXX/temp/temp.spec/temp.explicit/p4.cpp2
-rw-r--r--test/SemaCXX/cxx98-compat-pedantic.cpp3
4 files changed, 12 insertions, 1 deletions
diff --git a/include/clang/Basic/DiagnosticParseKinds.td b/include/clang/Basic/DiagnosticParseKinds.td
index 6247058287..32e9a08370 100644
--- a/include/clang/Basic/DiagnosticParseKinds.td
+++ b/include/clang/Basic/DiagnosticParseKinds.td
@@ -469,6 +469,11 @@ def err_missing_dependent_template_keyword : Error<
def warn_missing_dependent_template_keyword : ExtWarn<
"use 'template' keyword to treat '%0' as a dependent template name">;
+def ext_extern_template : Extension<
+ "extern templates are a C++11 extension">, InGroup<CXX11>;
+def warn_cxx98_compat_extern_template : Warning<
+ "extern templates are incompatible with C++98">,
+ InGroup<CXX98CompatPedantic>, DefaultIgnore;
def warn_static_inline_explicit_inst_ignored : Warning<
"ignoring '%select{static|inline}0' keyword on explicit template "
"instantiation">;
diff --git a/lib/Parse/Parser.cpp b/lib/Parse/Parser.cpp
index 2a1e2a2de8..2e0c46dbdb 100644
--- a/lib/Parse/Parser.cpp
+++ b/lib/Parse/Parser.cpp
@@ -642,6 +642,9 @@ Parser::ParseExternalDeclaration(ParsedAttributesWithRange &attrs,
// Extern templates
SourceLocation ExternLoc = ConsumeToken();
SourceLocation TemplateLoc = ConsumeToken();
+ Diag(ExternLoc, getLang().CPlusPlus0x ?
+ diag::warn_cxx98_compat_extern_template :
+ diag::ext_extern_template) << SourceRange(ExternLoc, TemplateLoc);
SourceLocation DeclEnd;
return Actions.ConvertDeclToDeclGroup(
ParseExplicitInstantiation(ExternLoc, TemplateLoc, DeclEnd));
diff --git a/test/CXX/temp/temp.spec/temp.explicit/p4.cpp b/test/CXX/temp/temp.spec/temp.explicit/p4.cpp
index d304374115..09c428e01d 100644
--- a/test/CXX/temp/temp.spec/temp.explicit/p4.cpp
+++ b/test/CXX/temp/temp.spec/temp.explicit/p4.cpp
@@ -43,6 +43,6 @@ namespace test0 {
// inappropriately instantiating this template.
void *ptr = x;
}
- extern template class foo<char>;
+ extern template class foo<char>; // expected-warning {{extern templates are a C++11 extension}}
template class foo<char>;
}
diff --git a/test/SemaCXX/cxx98-compat-pedantic.cpp b/test/SemaCXX/cxx98-compat-pedantic.cpp
index 28fc23a0a7..00532d5ac0 100644
--- a/test/SemaCXX/cxx98-compat-pedantic.cpp
+++ b/test/SemaCXX/cxx98-compat-pedantic.cpp
@@ -29,3 +29,6 @@ struct ConvertToInt {
operator int();
};
int *ArraySizeConversion = new int[ConvertToInt()]; // expected-warning {{implicit conversion from array size expression of type 'ConvertToInt' to integral type 'int' is incompatible with C++98}}
+
+template<typename T> class ExternTemplate {};
+extern template class ExternTemplate<int>; // expected-warning {{extern templates are incompatible with C++98}}