summaryrefslogtreecommitdiffstats
path: root/clang
diff options
context:
space:
mode:
authorFaisal Vali <faisalv@yahoo.com>2013-12-04 03:51:14 +0000
committerFaisal Vali <faisalv@yahoo.com>2013-12-04 03:51:14 +0000
commitcb7e5df97efa0d5cbe6e51902cd619bec1516f16 (patch)
treecd7e19f87665338b5a63528d117a2c29a0817786 /clang
parent0acd8a756133c48b9342444a5d32cac3fbcc9911 (diff)
downloadbcm5719-llvm-cb7e5df97efa0d5cbe6e51902cd619bec1516f16.tar.gz
bcm5719-llvm-cb7e5df97efa0d5cbe6e51902cd619bec1516f16.zip
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. llvm-svn: 196351
Diffstat (limited to 'clang')
-rw-r--r--clang/include/clang/Parse/Parser.h4
-rw-r--r--clang/lib/Parse/ParseTemplate.cpp6
-rw-r--r--clang/test/Parser/cxx-template-argument.cpp1
-rw-r--r--clang/test/Parser/cxx-template-decl.cpp77
4 files changed, 86 insertions, 2 deletions
diff --git a/clang/include/clang/Parse/Parser.h b/clang/include/clang/Parse/Parser.h
index 81ba5e1882e..f23d4fb8a53 100644
--- a/clang/include/clang/Parse/Parser.h
+++ b/clang/include/clang/Parse/Parser.h
@@ -193,6 +193,10 @@ class Parser : public CodeCompletionHandler {
++Depth;
++AddedLevels;
}
+ void addDepth(unsigned D) {
+ Depth += D;
+ AddedLevels += D;
+ }
unsigned getDepth() const { return Depth; }
};
diff --git a/clang/lib/Parse/ParseTemplate.cpp b/clang/lib/Parse/ParseTemplate.cpp
index 076edb93fa1..8275922a6e3 100644
--- a/clang/lib/Parse/ParseTemplate.cpp
+++ b/clang/lib/Parse/ParseTemplate.cpp
@@ -1304,9 +1304,11 @@ void Parser::ParseLateTemplatedFuncDef(LateParsedTemplate &LPT) {
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;
diff --git a/clang/test/Parser/cxx-template-argument.cpp b/clang/test/Parser/cxx-template-argument.cpp
index 8bf2a4f78ad..bbd53b2bdd6 100644
--- a/clang/test/Parser/cxx-template-argument.cpp
+++ b/clang/test/Parser/cxx-template-argument.cpp
@@ -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 {};
diff --git a/clang/test/Parser/cxx-template-decl.cpp b/clang/test/Parser/cxx-template-decl.cpp
index 81269ce2541..87429001223 100644
--- a/clang/test/Parser/cxx-template-decl.cpp
+++ b/clang/test/Parser/cxx-template-decl.cpp
@@ -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> struct shadow8 { // expected-note{{template
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));
+}
+
+}
OpenPOWER on IntegriCloud