aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/clang/Basic/DiagnosticParseKinds.td4
-rw-r--r--lib/Parse/Parser.cpp34
-rw-r--r--test/SemaTemplate/explicit-instantiation.cpp4
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;