]> granicus.if.org Git - clang/commitdiff
Moved diagnosis of forward declarations of variable templates from Parser to Sema.
authorLarisse Voufo <lvoufo@google.com>
Tue, 6 Aug 2013 03:43:07 +0000 (03:43 +0000)
committerLarisse Voufo <lvoufo@google.com>
Tue, 6 Aug 2013 03:43:07 +0000 (03:43 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@187768 91177308-0d34-0410-b5e6-96231b3b80d8

include/clang/AST/DeclTemplate.h
include/clang/Basic/DiagnosticParseKinds.td
include/clang/Basic/DiagnosticSemaKinds.td
include/clang/Sema/Sema.h
lib/Parse/ParseDecl.cpp
lib/Sema/SemaDecl.cpp
lib/Sema/SemaTemplateInstantiateDecl.cpp
test/Driver/crash-report.c

index 5d4ddc14aafbd380528535c1477e898c6dda9c2b..a0764054c7f2203599280746a22aa791596430b2 100644 (file)
@@ -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 *
index e9712a20d50d8c1bd5fba3e7a46c3fffb21c1b25..15c7c980c949837055f51fb8ae563fa76b496cd3 100644 (file)
@@ -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<
index cd909d443c79f3188735289bc04112b8c0001c72..1ef9c5a0590241d6248929fdebcea5d7096eea29 100644 (file)
@@ -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">;
index d0a5c60cd6126aa8dfb0e3da253176ae9be5c0ab..408c600aaa7f1de3a86876019f9d919ee10a3cd5 100644 (file)
@@ -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,
index 80fab62f41ef0ef1edd89c74ac9877a0133564d7..3f15b5b089a44b76156d76766bf55c8b7c0b2637 100644 (file)
@@ -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<VarTemplateDecl>(ThisDecl) ||
-         isa<VarTemplatePartialSpecializationDecl>(ThisDecl))) {
-      Diag(SS.getBeginLoc(), diag::err_forward_var_nested_name_specifier)
-          << isa<VarTemplatePartialSpecializationDecl>(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<VarTemplateDecl>(ThisDecl) : 0)
       // Re-direct this decl to refer to the templated decl so that we can
index 80ac1167ffa32903d2342fc64b171cc70198373d..15e6a492725e0a98b5abe5dccc9d5a76f90d0849 100644 (file)
@@ -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<VarTemplateDecl>(D) ||
+       isa<VarTemplatePartialSpecializationDecl>(D))) {
+    Diag(SS.getBeginLoc(), diag::err_forward_var_nested_name_specifier)
+      << isa<VarTemplatePartialSpecializationDecl>(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<CXXRecordDecl>(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))
index 0ca6611c3587fb21cadceb2a47b386d4c838ca37..b93fe9a966a4120fbb15d356c83e7c9f651a5698 100644 (file)
@@ -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() &&
index afac934714214826f2558a05183b37859d1daa9a..97dbeac7a6371aa5556981ebd747d3b52f77fd61 100644 (file)
@@ -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