From: Larisse Voufo Date: Tue, 6 Aug 2013 03:43:07 +0000 (+0000) Subject: Moved diagnosis of forward declarations of variable templates from Parser to Sema. X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=06935f32645c8965e398bbd141f9800eacdfd439;p=clang Moved diagnosis of forward declarations of variable templates from Parser to Sema. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@187768 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/clang/AST/DeclTemplate.h b/include/clang/AST/DeclTemplate.h index 5d4ddc14aa..a0764054c7 100644 --- a/include/clang/AST/DeclTemplate.h +++ b/include/clang/AST/DeclTemplate.h @@ -2560,7 +2560,7 @@ class VarTemplatePartialSpecializationDecl VarTemplatePartialSpecializationDecl() : VarTemplateSpecializationDecl(VarTemplatePartialSpecialization), TemplateParams(0), ArgsAsWritten(0), NumArgsAsWritten(0), - SequenceNumber(0), InstantiatedFromMember(0, false) {} + SequenceNumber(SequenceNumber), InstantiatedFromMember(0, false) {} public: static VarTemplatePartialSpecializationDecl * diff --git a/include/clang/Basic/DiagnosticParseKinds.td b/include/clang/Basic/DiagnosticParseKinds.td index e9712a20d5..15c7c980c9 100644 --- a/include/clang/Basic/DiagnosticParseKinds.td +++ b/include/clang/Basic/DiagnosticParseKinds.td @@ -606,10 +606,6 @@ def err_explicit_instantiation_enum : Error< "enumerations cannot be explicitly instantiated">; def err_expected_template_parameter : Error<"expected template parameter">; -def err_forward_var_nested_name_specifier : Error< - "forward declaration of variable template%select{| partial specialization}0 cannot " - "have a nested name specifier">; - def err_missing_dependent_template_keyword : Error< "use 'template' keyword to treat '%0' as a dependent template name">; def warn_missing_dependent_template_keyword : ExtWarn< diff --git a/include/clang/Basic/DiagnosticSemaKinds.td b/include/clang/Basic/DiagnosticSemaKinds.td index cd909d443c..1ef9c5a059 100644 --- a/include/clang/Basic/DiagnosticSemaKinds.td +++ b/include/clang/Basic/DiagnosticSemaKinds.td @@ -4398,6 +4398,9 @@ def ext_standalone_specifier : ExtWarn<"'%0' is not permitted on a declaration " def err_standalone_class_nested_name_specifier : Error< "forward declaration of %select{class|struct|interface|union|enum}0 cannot " "have a nested name specifier">; +def err_forward_var_nested_name_specifier : Error< + "forward declaration of variable template%select{| partial specialization}0 cannot " + "have a nested name specifier">; def err_typecheck_sclass_func : Error<"illegal storage class on function">; def err_static_block_func : Error< "function declared in block scope cannot have 'static' storage class">; diff --git a/include/clang/Sema/Sema.h b/include/clang/Sema/Sema.h index d0a5c60cd6..408c600aaa 100644 --- a/include/clang/Sema/Sema.h +++ b/include/clang/Sema/Sema.h @@ -1461,6 +1461,7 @@ public: LookupResult &Previous); NamedDecl* ActOnTypedefNameDecl(Scope* S, DeclContext* DC, TypedefNameDecl *D, LookupResult &Previous, bool &Redeclaration); + bool HandleVariableRedeclaration(Decl *D, CXXScopeSpec &SS); NamedDecl *ActOnVariableDeclarator(Scope *S, Declarator &D, DeclContext *DC, TypeSourceInfo *TInfo, LookupResult &Previous, diff --git a/lib/Parse/ParseDecl.cpp b/lib/Parse/ParseDecl.cpp index 80fab62f41..3f15b5b089 100644 --- a/lib/Parse/ParseDecl.cpp +++ b/lib/Parse/ParseDecl.cpp @@ -1801,21 +1801,11 @@ Decl *Parser::ParseDeclarationAfterDeclaratorAndAttributes(Declarator &D, ThisDecl = Actions.ActOnTemplateDeclarator(getCurScope(), *TemplateInfo.TemplateParams, D); - - // If this is a forward declaration of a variable template or variable - // template partial specialization with nested name specifier, complain. - // FIXME: Move to Sema. - CXXScopeSpec &SS = D.getCXXScopeSpec(); - if (Tok.is(tok::semi) && ThisDecl && SS.isNotEmpty() && - (isa(ThisDecl) || - isa(ThisDecl))) { - Diag(SS.getBeginLoc(), diag::err_forward_var_nested_name_specifier) - << isa(ThisDecl) - << SS.getRange(); + if (Tok.is(tok::semi) && + Actions.HandleVariableRedeclaration(ThisDecl, D.getCXXScopeSpec())) { SkipUntil(tok::semi, true, true); return 0; } - if (VarTemplateDecl *VT = ThisDecl ? dyn_cast(ThisDecl) : 0) // Re-direct this decl to refer to the templated decl so that we can diff --git a/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp index 80ac1167ff..15e6a49272 100644 --- a/lib/Sema/SemaDecl.cpp +++ b/lib/Sema/SemaDecl.cpp @@ -4770,6 +4770,21 @@ static bool shouldConsiderLinkage(const FunctionDecl *FD) { llvm_unreachable("Unexpected context"); } +bool Sema::HandleVariableRedeclaration(Decl *D, CXXScopeSpec &SS) { + // If this is a redeclaration of a variable template or a forward + // declaration of a variable template partial specialization + // with nested name specifier, complain. + + if (D && SS.isNotEmpty() && + (isa(D) || + isa(D))) { + Diag(SS.getBeginLoc(), diag::err_forward_var_nested_name_specifier) + << isa(D) << SS.getRange(); + return true; + } + return false; +} + NamedDecl * Sema::ActOnVariableDeclarator(Scope *S, Declarator &D, DeclContext *DC, TypeSourceInfo *TInfo, LookupResult &Previous, @@ -4907,7 +4922,8 @@ Sema::ActOnVariableDeclarator(Scope *S, Declarator &D, DeclContext *DC, case SC_OpenCLWorkGroupLocal: llvm_unreachable("OpenCL storage class in c++!"); } - } + } + if (SC == SC_Static && CurContext->isRecord()) { if (const CXXRecordDecl *RD = dyn_cast(DC)) { if (RD->isLocalClass()) @@ -4966,7 +4982,7 @@ Sema::ActOnVariableDeclarator(Scope *S, Declarator &D, DeclContext *DC, IsPartialSpecialization = TemplateParams->size() > 0; } else { // if (TemplateParams->size() > 0) - // This is a template declaration. + // This is a template declaration. // Check that we can declare a template here. if (CheckTemplateDeclScope(S, TemplateParams)) diff --git a/lib/Sema/SemaTemplateInstantiateDecl.cpp b/lib/Sema/SemaTemplateInstantiateDecl.cpp index 0ca6611c35..b93fe9a966 100644 --- a/lib/Sema/SemaTemplateInstantiateDecl.cpp +++ b/lib/Sema/SemaTemplateInstantiateDecl.cpp @@ -3461,7 +3461,6 @@ void Sema::InstantiateVariableDefinition(SourceLocation PointOfInstantiation, VarSpec->getTemplateArgsInfo(), InstantiationDependent) && "Only instantiate variable template specializations that are " "not type-dependent"); - (void)InstantiationDependent; // Find the variable initialization that we'll be substituting. assert(VarSpec->getSpecializedTemplate() && diff --git a/test/Driver/crash-report.c b/test/Driver/crash-report.c index afac934714..97dbeac7a6 100644 --- a/test/Driver/crash-report.c +++ b/test/Driver/crash-report.c @@ -14,9 +14,6 @@ // RUN: not env FORCE_CLANG_DIAGNOSTICS_CRASH=1 %clang -fsyntax-only -x c /dev/null 2>&1 | FileCheck %s -// FIXME: Investigating. "fatal error: file 'nul' modified since it was first processed" -// XFAIL: mingw32 - #pragma clang __debug parser_crash // CHECK: Preprocessed source(s) and associated run script(s) are located at: // CHECK-NEXT: note: diagnostic msg: {{.*}}.c