summaryrefslogtreecommitdiffstats
path: root/clang/test/PCH/cxx-local-templates.cpp
diff options
context:
space:
mode:
authorFaisal Vali <faisalv@yahoo.com>2013-06-26 02:34:24 +0000
committerFaisal Vali <faisalv@yahoo.com>2013-06-26 02:34:24 +0000
commit18d3598ed0eb8b459a446cac037206caa4066208 (patch)
tree55a1a62286aeb8f093da09a7d20c0feca6ca8a42 /clang/test/PCH/cxx-local-templates.cpp
parent358256c77ad41d3502b4bdbc820a9598bc610ac7 (diff)
downloadbcm5719-llvm-18d3598ed0eb8b459a446cac037206caa4066208.tar.gz
bcm5719-llvm-18d3598ed0eb8b459a446cac037206caa4066208.zip
Fix PCH bug with member templates of local classes in nontemplate functions.
As noted by Richard in the post: http://lists.cs.uiuc.edu/pipermail/cfe-commits/Week-of-Mon-20130624/082605.html, the following code should not add an entry into PendingLocalImplicitInstantiations, since local instantiations should only occur within the context of other instantiations: int foo(double y) { struct Lambda { template<class T> T operator()(T t) const { return t; }; } lambda; return lambda(y); } Hence the attached code does the following: 1) In MarkFunctionReferenced, check if ActiveInstantiations.size() is non-zero before adding to PendingLocalImplicitInstantiations. 2) In InstantiateFunctionDefinition, we swap out/in PendingLocalImplicitInstantiations so that only those pending local instantiations that are added during the instantiation of the current function are instantiated recursively. llvm-svn: 184903
Diffstat (limited to 'clang/test/PCH/cxx-local-templates.cpp')
-rw-r--r--clang/test/PCH/cxx-local-templates.cpp55
1 files changed, 55 insertions, 0 deletions
diff --git a/clang/test/PCH/cxx-local-templates.cpp b/clang/test/PCH/cxx-local-templates.cpp
new file mode 100644
index 00000000000..277ad831099
--- /dev/null
+++ b/clang/test/PCH/cxx-local-templates.cpp
@@ -0,0 +1,55 @@
+// RUN: %clang_cc1 -pedantic-errors -std=c++11 -emit-pch %s -o %t-cxx11
+// RUN: %clang_cc1 -ast-print -pedantic-errors -std=c++11 -include-pch %t-cxx11 %s | FileCheck -check-prefix=CHECK-PRINT %s
+
+#ifndef HEADER_INCLUDED
+
+#define HEADER_INCLUDED
+
+int nontemplate_test(double d) {
+ struct Local {
+ template<class T> T foo(T t) {
+ return t;
+ }
+ };
+ return Local{}.foo(d);
+}
+
+template<class U>
+U template_test(U d) {
+ struct Local {
+ template<class T> T foo(T t) {
+ return t;
+ }
+ };
+ return Local{}.foo(d);
+}
+
+int nested_local() {
+ struct Inner1 {
+ int inner1_foo(char c) {
+ struct Inner2 {
+ template<class T> T inner2_foo(T t) {
+ return t;
+ }
+ };
+ return Inner2{}.inner2_foo(3.14);
+ }
+ };
+ return Inner1{}.inner1_foo('a');
+}
+
+#else
+
+// CHECK-PRINT: U template_test
+
+// CHECK-PRINT: int nontemplate_test(double)
+
+int nontemplate_test(double);
+
+template double template_test(double);
+int test2(int y) {
+ return nontemplate_test(y) + template_test(y);
+}
+
+
+#endif
OpenPOWER on IntegriCloud