diff options
author | Richard Smith <richard-llvm@metafoo.co.uk> | 2011-10-20 18:35:58 +0000 |
---|---|---|
committer | Richard Smith <richard-llvm@metafoo.co.uk> | 2011-10-20 18:35:58 +0000 |
commit | 9324583ad2afd09db8c9967cd05c4fa44bac9555 (patch) | |
tree | db3dc524af9e6041c57f4f87432733a1a5574f10 | |
parent | cb8f951deacd251d9b3a73dc65f341477e039de1 (diff) |
'extern template' is a C++11 feature. Add an Extension for C++98 (this matches
gcc's behaviour), and a -Wc++98-compat-pedantic warning for C++11.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@142597 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | include/clang/Basic/DiagnosticParseKinds.td | 5 | ||||
-rw-r--r-- | lib/Parse/Parser.cpp | 3 | ||||
-rw-r--r-- | test/CXX/temp/temp.spec/temp.explicit/p4.cpp | 2 | ||||
-rw-r--r-- | test/SemaCXX/cxx98-compat-pedantic.cpp | 3 |
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}} |