[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