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