[cfe-commits] r76756 - in /cfe/trunk: include/clang/Basic/DiagnosticSemaKinds.td lib/Sema/Sema.h lib/Sema/SemaDecl.cpp test/CXX/temp/temp.decls/temp.class/temp.static/p1.cpp test/Parser/cxx-template-decl.cpp

Douglas Gregor dgregor at apple.com
Wed Jul 22 10:18:37 PDT 2009


Author: dgregor
Date: Wed Jul 22 12:18:37 2009
New Revision: 76756

URL: http://llvm.org/viewvc/llvm-project?rev=76756&view=rev
Log:
Implement parsing and semantic analysis for out-of-line definitions of static
data members of class templates. We don't instantiate the definitions yet,
however.

Added:
    cfe/trunk/test/CXX/temp/temp.decls/temp.class/temp.static/p1.cpp
Modified:
    cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
    cfe/trunk/lib/Sema/Sema.h
    cfe/trunk/lib/Sema/SemaDecl.cpp
    cfe/trunk/test/Parser/cxx-template-decl.cpp

Modified: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td?rev=76756&r1=76755&r2=76756&view=diff

==============================================================================
--- cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td Wed Jul 22 12:18:37 2009
@@ -722,6 +722,9 @@
 def err_template_param_default_arg_missing : Error<
   "template parameter missing a default argument">;
 
+def err_template_variable : Error<"variable %0 declared as a template">;
+def err_template_variable_noparams : Error<
+  "extraneous 'template<>' in declaration of variable %0">;
 // C++ Template Argument Lists
 def err_template_arg_list_different_arity : Error<
   "%select{too few|too many}0 template arguments for "

Modified: cfe/trunk/lib/Sema/Sema.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/Sema.h?rev=76756&r1=76755&r2=76756&view=diff

==============================================================================
--- cfe/trunk/lib/Sema/Sema.h (original)
+++ cfe/trunk/lib/Sema/Sema.h Wed Jul 22 12:18:37 2009
@@ -443,6 +443,7 @@
                                     bool &Redeclaration);
   NamedDecl* ActOnVariableDeclarator(Scope* S, Declarator& D, DeclContext* DC,
                                      QualType R, NamedDecl* PrevDecl,
+                                     MultiTemplateParamsArg TemplateParamLists,
                                      bool &Redeclaration);
   void CheckVariableDeclaration(VarDecl *NewVD, NamedDecl *PrevDecl,
                                 bool &Redeclaration);

Modified: cfe/trunk/lib/Sema/SemaDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDecl.cpp?rev=76756&r1=76755&r2=76756&view=diff

==============================================================================
--- cfe/trunk/lib/Sema/SemaDecl.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDecl.cpp Wed Jul 22 12:18:37 2009
@@ -1520,7 +1520,9 @@
                                   move(TemplateParamLists),
                                   IsFunctionDefinition, Redeclaration);
   } else {
-    New = ActOnVariableDeclarator(S, D, DC, R, PrevDecl, Redeclaration);
+    New = ActOnVariableDeclarator(S, D, DC, R, PrevDecl, 
+                                  move(TemplateParamLists),
+                                  Redeclaration);
   }
 
   if (New == 0)
@@ -1772,6 +1774,7 @@
 NamedDecl*
 Sema::ActOnVariableDeclarator(Scope* S, Declarator& D, DeclContext* DC,
                               QualType R,NamedDecl* PrevDecl,
+                              MultiTemplateParamsArg TemplateParamLists,
                               bool &Redeclaration) {
   DeclarationName Name = GetNameForDeclarator(D);
 
@@ -1840,7 +1843,36 @@
     }
   }
         
-    
+  // Check that we can declare a template here.
+  if (TemplateParamLists.size() && 
+      CheckTemplateDeclScope(S, TemplateParamLists))
+    return 0;
+  
+  // Match up the template parameter lists with the scope specifier, then
+  // determine whether we have a template or a template specialization.
+  if (TemplateParameterList *TemplateParams
+      = MatchTemplateParametersToScopeSpecifier(
+                                  D.getDeclSpec().getSourceRange().getBegin(),
+                                                D.getCXXScopeSpec(),
+                        (TemplateParameterList**)TemplateParamLists.release(),
+                                                 TemplateParamLists.size())) {
+    if (TemplateParams->size() > 0) {
+      // There is no such thing as a variable template.
+      Diag(D.getIdentifierLoc(), diag::err_template_variable)
+        << II
+        << SourceRange(TemplateParams->getTemplateLoc(),
+                       TemplateParams->getRAngleLoc());
+      return 0;
+    } else {
+      // There is an extraneous 'template<>' for this variable. Complain
+      // about it, but allow the declaration of the variable.
+      Diag(TemplateParams->getTemplateLoc(), diag::err_template_variable)
+        << II
+        << SourceRange(TemplateParams->getTemplateLoc(),
+                       TemplateParams->getRAngleLoc());          
+    }
+  }        
+  
   // The variable can not 
   NewVD = VarDecl::Create(Context, DC, D.getIdentifierLoc(), 
                           II, R, SC, 
@@ -2209,8 +2241,7 @@
     } else {
       // FIXME: Handle function template specializations
     }
-  }
-        
+  }        
   
   // C++ [dcl.fct.spec]p5:
   //   The virtual specifier shall only be used in declarations of

Added: cfe/trunk/test/CXX/temp/temp.decls/temp.class/temp.static/p1.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/temp/temp.decls/temp.class/temp.static/p1.cpp?rev=76756&view=auto

==============================================================================
--- cfe/trunk/test/CXX/temp/temp.decls/temp.class/temp.static/p1.cpp (added)
+++ cfe/trunk/test/CXX/temp/temp.decls/temp.class/temp.static/p1.cpp Wed Jul 22 12:18:37 2009
@@ -0,0 +1,26 @@
+// RUN: clang-cc -fsyntax-only -verify %s
+
+template<typename T>
+struct X0 {
+  static T value;
+};
+
+template<typename T>
+T X0<T>::value = 0;
+
+struct X1 { 
+  X1(int);
+};
+
+struct X2 { };
+
+int& get_int() { return X0<int>::value; }
+X1& get_X1() { return X0<X1>::value; }
+
+double*& get_double_ptr() { return X0<int*>::value; } // expected-error{{initialized}}
+
+X2& get_X2() { 
+  return X0<X2>::value; // FIXME: instantiation should fail!
+}
+  
+template<typename T> T x; // expected-error{{variable 'x' declared as a template}}
\ No newline at end of file

Modified: cfe/trunk/test/Parser/cxx-template-decl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Parser/cxx-template-decl.cpp?rev=76756&r1=76755&r2=76756&view=diff

==============================================================================
--- cfe/trunk/test/Parser/cxx-template-decl.cpp (original)
+++ cfe/trunk/test/Parser/cxx-template-decl.cpp Wed Jul 22 12:18:37 2009
@@ -5,7 +5,8 @@
 template  x;            // expected-error {{C++ requires a type specifier for all declarations}}
 export template x;      // expected-error {{expected '<' after 'template'}} \
                         // expected-note {{exported templates are unsupported}} \
-// expected-error {{C++ requires a type specifier for all declarations}}
+// expected-error {{C++ requires a type specifier for all declarations}} \
+// expected-error {{declared as a template}}
 // See Sema::ParsedFreeStandingDeclSpec about the double diagnostic. This is
 // because ParseNonTypeTemplateParameter starts parsing a DeclSpec.
 template < ;            // expected-error {{parse error}} expected-error {{declaration does not declare anything}}





More information about the cfe-commits mailing list