r196351 - Fix PR17637: incorrect calculation of template parameter depth

Faisal Vali faisalv at yahoo.com
Tue Dec 3 19:51:14 PST 2013


Author: faisalv
Date: Tue Dec  3 21:51:14 2013
New Revision: 196351

URL: http://llvm.org/viewvc/llvm-project?rev=196351&view=rev
Log:
Fix PR17637: incorrect calculation of template parameter depth

In delayed template parsing mode, adjust the template depth counter for each template parameter list associated with an out of line member template specialization.

Modified:
    cfe/trunk/include/clang/Parse/Parser.h
    cfe/trunk/lib/Parse/ParseTemplate.cpp
    cfe/trunk/test/Parser/cxx-template-argument.cpp
    cfe/trunk/test/Parser/cxx-template-decl.cpp

Modified: cfe/trunk/include/clang/Parse/Parser.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Parse/Parser.h?rev=196351&r1=196350&r2=196351&view=diff
==============================================================================
--- cfe/trunk/include/clang/Parse/Parser.h (original)
+++ cfe/trunk/include/clang/Parse/Parser.h Tue Dec  3 21:51:14 2013
@@ -193,6 +193,10 @@ class Parser : public CodeCompletionHand
       ++Depth;
       ++AddedLevels;
     }
+    void addDepth(unsigned D) {
+      Depth += D;
+      AddedLevels += D;
+    }
     unsigned getDepth() const { return Depth; }
   };
 

Modified: cfe/trunk/lib/Parse/ParseTemplate.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseTemplate.cpp?rev=196351&r1=196350&r2=196351&view=diff
==============================================================================
--- cfe/trunk/lib/Parse/ParseTemplate.cpp (original)
+++ cfe/trunk/lib/Parse/ParseTemplate.cpp Tue Dec  3 21:51:14 2013
@@ -1304,9 +1304,11 @@ void Parser::ParseLateTemplatedFuncDef(L
       new ParseScope(this, Scope::TemplateParamScope));
 
   DeclaratorDecl *Declarator = dyn_cast<DeclaratorDecl>(FunD);
-  if (Declarator && Declarator->getNumTemplateParameterLists() != 0) {
+  const unsigned DeclaratorNumTemplateParameterLists = 
+      (Declarator ? Declarator->getNumTemplateParameterLists() : 0);
+  if (Declarator && DeclaratorNumTemplateParameterLists != 0) {
     Actions.ActOnReenterDeclaratorTemplateScope(getCurScope(), Declarator);
-    ++CurTemplateDepthTracker;
+    CurTemplateDepthTracker.addDepth(DeclaratorNumTemplateParameterLists);
   }
   Actions.ActOnReenterTemplateScope(getCurScope(), LPT.D);
   ++CurTemplateDepthTracker;

Modified: cfe/trunk/test/Parser/cxx-template-argument.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Parser/cxx-template-argument.cpp?rev=196351&r1=196350&r2=196351&view=diff
==============================================================================
--- cfe/trunk/test/Parser/cxx-template-argument.cpp (original)
+++ cfe/trunk/test/Parser/cxx-template-argument.cpp Tue Dec  3 21:51:14 2013
@@ -1,4 +1,5 @@
 // RUN: %clang_cc1 -fsyntax-only -verify %s
+// RUN: %clang_cc1 -fsyntax-only -verify %s -fdelayed-template-parsing
 
 template<typename T> struct A {};
 

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=196351&r1=196350&r2=196351&view=diff
==============================================================================
--- cfe/trunk/test/Parser/cxx-template-decl.cpp (original)
+++ cfe/trunk/test/Parser/cxx-template-decl.cpp Tue Dec  3 21:51:14 2013
@@ -1,4 +1,7 @@
 // RUN: %clang_cc1 -fsyntax-only -verify %s
+// RUN: %clang_cc1 -fsyntax-only -verify %s -fdelayed-template-parsing -DDELAYED_TEMPLATE_PARSING
+
+
 
 // Errors
 export class foo { };   // expected-error {{expected template}}
@@ -102,7 +105,11 @@ template<template<typename> class T> str
 template<int Size> 
 void f(int& i) {
   i = Size;
+ #ifdef DELAYED_TEMPLATE_PARSING
+  Size = i; 
+ #else
   Size = i; // expected-error{{expression is not assignable}}
+ #endif
 }
 
 template<typename T>
@@ -127,3 +134,73 @@ namespace PR6184 {
   template <typename T>
   void N::bar(typename T::x) { }
 }
+
+// This PR occurred only in template parsing mode.
+namespace PR17637 {
+template <int>
+struct L {
+  template <typename T>
+  struct O {
+    template <typename U>
+    static void Fun(U);
+  };
+};
+
+template <int k>
+template <typename T>
+template <typename U>
+void L<k>::O<T>::Fun(U) {}
+
+void Instantiate() { L<0>::O<int>::Fun(0); }
+
+}
+
+namespace explicit_partial_specializations {
+typedef char (&oneT)[1];
+typedef char (&twoT)[2];
+typedef char (&threeT)[3];
+typedef char (&fourT)[4];
+typedef char (&fiveT)[5];
+typedef char (&sixT)[6];
+
+char one[1];
+char two[2];
+char three[3];
+char four[4];
+char five[5];
+char six[6];
+
+template<bool b> struct bool_ { typedef int type; };
+template<> struct bool_<false> {  };
+
+#define XCAT(x,y) x ## y
+#define CAT(x,y) XCAT(x,y)
+#define sassert(_b_) bool_<(_b_)>::type CAT(var, __LINE__);
+
+
+template <int>
+struct L {
+  template <typename T>
+  struct O {
+    template <typename U>
+    static oneT Fun(U);
+    
+  };
+};
+template <int k>
+template <typename T>
+template <typename U>
+oneT L<k>::O<T>::Fun(U) { return one; }
+
+template<>
+template<>
+template<typename U>
+oneT L<0>::O<char>::Fun(U) { return one; }
+
+
+void Instantiate() { 
+  sassert(sizeof(L<0>::O<int>::Fun(0)) == sizeof(one)); 
+  sassert(sizeof(L<0>::O<char>::Fun(0)) == sizeof(one));
+}
+
+}





More information about the cfe-commits mailing list