aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDouglas Gregor <dgregor@apple.com>2010-12-01 20:32:20 +0000
committerDouglas Gregor <dgregor@apple.com>2010-12-01 20:32:20 +0000
commit7306ebfacfa51ba5270fd20f162f62d2ed813485 (patch)
tree67b8269853ad8f36b3adc4678f0535f77b7ec8f6
parente343583370ba7465273645a300b9a829e3a95d82 (diff)
Not content to implement just "extern" explicit template
instantiations, GCC also supports "inline" and "static" explicit template instantiations. Parse and warn about such constructs, but don't implement the semantics of either "inline" or "static". They don't seem to be widely used. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@120599 91177308-0d34-0410-b5e6-96231b3b80d8
-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;