diff options
-rw-r--r-- | include/clang/Basic/DiagnosticParseKinds.td | 4 | ||||
-rw-r--r-- | lib/Parse/Parser.cpp | 34 | ||||
-rw-r--r-- | test/SemaTemplate/explicit-instantiation.cpp | 4 |
3 files changed, 38 insertions, 4 deletions
diff --git a/include/clang/Basic/DiagnosticParseKinds.td b/include/clang/Basic/DiagnosticParseKinds.td index ee0c5b3266..7a2cb711ff 100644 --- a/include/clang/Basic/DiagnosticParseKinds.td +++ b/include/clang/Basic/DiagnosticParseKinds.td @@ -348,6 +348,10 @@ def err_enum_template : Error<"enumeration cannot be a template">; def err_missing_dependent_template_keyword : Error< "use 'template' keyword to treat '%0' as a dependent template name">; +def warn_static_inline_explicit_inst_ignored : Warning< + "ignoring '%select{static|inline}0' keyword on explicit template " + "instantiation">; + // Constructor template diagnostics. def err_out_of_line_constructor_template_id : Error< "out-of-line constructor for %0 cannot have template arguments">; diff --git a/lib/Parse/Parser.cpp b/lib/Parse/Parser.cpp index fefe7871df..f5e4bfb649 100644 --- a/lib/Parse/Parser.cpp +++ b/lib/Parse/Parser.cpp @@ -525,12 +525,38 @@ Parser::DeclGroupPtrTy Parser::ParseExternalDeclaration(CXX0XAttributeList Attr, return ParseDeclaration(Stmts, Declarator::FileContext, DeclEnd, Attr); } - case tok::kw_inline: - if (getLang().CPlusPlus && NextToken().is(tok::kw_namespace)) { - // Inline namespaces. Allowed as an extension even in C++03. + case tok::kw_static: + // Parse (then ignore) 'static' prior to a template instantiation. This is + // a GCC extension that we intentionally do not support. + if (getLang().CPlusPlus && NextToken().is(tok::kw_template)) { + Diag(ConsumeToken(), diag::warn_static_inline_explicit_inst_ignored) + << 0; SourceLocation DeclEnd; StmtVector Stmts(Actions); - return ParseDeclaration(Stmts, Declarator::FileContext, DeclEnd, Attr); + return ParseDeclaration(Stmts, Declarator::FileContext, DeclEnd, Attr); + } + goto dont_know; + + case tok::kw_inline: + if (getLang().CPlusPlus) { + tok::TokenKind NextKind = NextToken().getKind(); + + // Inline namespaces. Allowed as an extension even in C++03. + if (NextKind == tok::kw_namespace) { + SourceLocation DeclEnd; + StmtVector Stmts(Actions); + return ParseDeclaration(Stmts, Declarator::FileContext, DeclEnd, Attr); + } + + // Parse (then ignore) 'inline' prior to a template instantiation. This is + // a GCC extension that we intentionally do not support. + if (NextKind == tok::kw_template) { + Diag(ConsumeToken(), diag::warn_static_inline_explicit_inst_ignored) + << 1; + SourceLocation DeclEnd; + StmtVector Stmts(Actions); + return ParseDeclaration(Stmts, Declarator::FileContext, DeclEnd, Attr); + } } goto dont_know; diff --git a/test/SemaTemplate/explicit-instantiation.cpp b/test/SemaTemplate/explicit-instantiation.cpp index 3a1446e8dd..ffec3c2b97 100644 --- a/test/SemaTemplate/explicit-instantiation.cpp +++ b/test/SemaTemplate/explicit-instantiation.cpp @@ -84,6 +84,10 @@ namespace explicit_instantiation_after_implicit_instantiation { template struct X0<1>; } +template<typename> struct X3 { }; +inline template struct X3<int>; // expected-warning{{ignoring 'inline' keyword on explicit template instantiation}} +static template struct X3<float>; // expected-warning{{ignoring 'static' keyword on explicit template instantiation}} + namespace PR7622 { // expected-note{{to match this}} template<typename,typename=int> struct basic_streambuf; |