]> granicus.if.org Git - clang/commitdiff
Not content to implement just "extern" explicit template
authorDouglas Gregor <dgregor@apple.com>
Wed, 1 Dec 2010 20:32:20 +0000 (20:32 +0000)
committerDouglas Gregor <dgregor@apple.com>
Wed, 1 Dec 2010 20:32:20 +0000 (20:32 +0000)
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

include/clang/Basic/DiagnosticParseKinds.td
lib/Parse/Parser.cpp
test/SemaTemplate/explicit-instantiation.cpp

index ee0c5b326679eec70ddaa344134db3d25a63f1aa..7a2cb711ff4e37fef37643b0ca9fb8344bc348a8 100644 (file)
@@ -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">;
index fefe7871df00bb66c92a6ac9bd2d45a871e0501a..f5e4bfb649854755199adefc28bccb354343d8be 100644 (file)
@@ -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;
 
index 3a1446e8dd6730ea1ec682acf2a5eab9897c49e3..ffec3c2b97f0170b8e0ebdf995bdb3c072714d2a 100644 (file)
@@ -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;