diff options
author | David Majnemer <david.majnemer@gmail.com> | 2013-11-27 08:20:38 +0000 |
---|---|---|
committer | David Majnemer <david.majnemer@gmail.com> | 2013-11-27 08:20:38 +0000 |
commit | 8b5933a189b15f42798030bbdc1a82af434c6beb (patch) | |
tree | cba8ce7fd3233d00acc1f68ebe521eaa495c66ed /test | |
parent | 070d649eefeeb17cce3afaeebe9f825024284854 (diff) | |
download | clang-8b5933a189b15f42798030bbdc1a82af434c6beb.tar.gz |
Sema: Instantiate local class and their members appropriately
We would fail to instantiate them when the surrounding function was
instantiated. Instantiate the class and add it's members to the list of
pending instantiations, they should be resolved when we are finished
with the function's body.
This fixes PR9685.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@195827 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'test')
-rw-r--r-- | test/CXX/temp/temp.spec/temp.inst/p1.cpp | 11 | ||||
-rw-r--r-- | test/SemaTemplate/instantiate-local-class.cpp | 96 |
2 files changed, 100 insertions, 7 deletions
diff --git a/test/CXX/temp/temp.spec/temp.inst/p1.cpp b/test/CXX/temp/temp.spec/temp.inst/p1.cpp index 8684fc4dab..adf812b714 100644 --- a/test/CXX/temp/temp.spec/temp.inst/p1.cpp +++ b/test/CXX/temp/temp.spec/temp.inst/p1.cpp @@ -33,24 +33,23 @@ namespace ScopedEnum { ScopedEnum1<double>::E e1; // ok ScopedEnum1<double>::E e2 = decltype(e2)::e; // expected-note {{in instantiation of enumeration 'ScopedEnum::ScopedEnum1<double>::E' requested here}} - // The behavior for enums defined within function templates is not clearly - // specified by the standard. We follow the rules for enums defined within - // class templates. + // DR1484 specifies that enumerations cannot be separately instantiated, + // they will be instantiated with the rest of the template declaration. template<typename T> int f() { enum class E { - e = T::error + e = T::error // expected-error {{has no members}} }; return (int)E(); } - int test1 = f<int>(); + int test1 = f<int>(); // expected-note {{here}} template<typename T> int g() { enum class E { e = T::error // expected-error {{has no members}} }; - return E::e; // expected-note {{here}} + return E::e; } int test2 = g<int>(); // expected-note {{here}} } diff --git a/test/SemaTemplate/instantiate-local-class.cpp b/test/SemaTemplate/instantiate-local-class.cpp index c151fbb9a5..2b5db0fda3 100644 --- a/test/SemaTemplate/instantiate-local-class.cpp +++ b/test/SemaTemplate/instantiate-local-class.cpp @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -verify %s +// RUN: %clang_cc1 -verify -std=c++11 %s // expected-no-diagnostics template<typename T> void f0() { @@ -66,3 +66,97 @@ namespace PR8801 { template void foo<Y>(); } + +namespace TemplatePacksAndLambdas { + template <typename ...T> int g(T...); + struct S { + template <typename ...T> static void f(int f = g([]{ static T t; return ++t; }()...)) {} + }; + void h() { S::f<int, int, int>(); } +} + +namespace PR9685 { + template <class Thing> void forEach(Thing t) { t.func(); } + + template <typename T> void doIt() { + struct Functor { + void func() { (void)i; } + int i; + }; + + forEach(Functor()); + } + + void call() { + doIt<int>(); + } +} + +namespace PR12702 { + struct S { + template <typename F> bool apply(F f) { return f(); } + }; + + template <typename> struct T { + void foo() { + struct F { + int x; + + bool operator()() { return x == 0; } + }; + + S().apply(F()); + } + }; + + void call() { T<int>().foo(); } +} + +namespace PR17139 { + template <class T> void foo(const T &t) { t.foo(); } + + template <class F> void bar(F *f) { + struct B { + F *fn; + void foo() const { fn(); } + } b = { f }; + foo(b); + } + + void go() {} + + void test() { bar(go); } +} + +namespace PR17740 { +class C { +public: + template <typename T> static void foo(T function); + template <typename T> static void bar(T function); + template <typename T> static void func(T function); +}; + +template <typename T> void C::foo(T function) { function(); } + +template <typename T> void C::bar(T function) { + foo([&function]() { function(); }); +} + +template <typename T> void C::func(T function) { + struct Struct { + T mFunction; + + Struct(T function) : mFunction(function) {}; + + void operator()() { + mFunction(); + }; + }; + + bar(Struct(function)); +} + +void call() { + C::func([]() {}); +} +} |