1762bb9d0ad20320b9f97a841dce57ba5e8e48b07Richard Smith// RUN: %clang_cc1 -std=c++11 -fsyntax-only -verify %s
28e8fb3be5bd78f0564444eca02b404566a5f3b5dAndy Gibbs// expected-no-diagnostics
3ea6c96f63a45b4ffdcdf9824a9cf31a32825c0f6Douglas Gregor
4ea6c96f63a45b4ffdcdf9824a9cf31a32825c0f6Douglas Gregornamespace ParameterPacksWithFunctions {
5ea6c96f63a45b4ffdcdf9824a9cf31a32825c0f6Douglas Gregor  template<typename ...> struct count;
6ea6c96f63a45b4ffdcdf9824a9cf31a32825c0f6Douglas Gregor
7ea6c96f63a45b4ffdcdf9824a9cf31a32825c0f6Douglas Gregor  template<typename Head, typename ...Tail>
8ea6c96f63a45b4ffdcdf9824a9cf31a32825c0f6Douglas Gregor  struct count<Head, Tail...> {
9ea6c96f63a45b4ffdcdf9824a9cf31a32825c0f6Douglas Gregor    static const unsigned value = 1 + count<Tail...>::value;
10ea6c96f63a45b4ffdcdf9824a9cf31a32825c0f6Douglas Gregor  };
11ea6c96f63a45b4ffdcdf9824a9cf31a32825c0f6Douglas Gregor
12ea6c96f63a45b4ffdcdf9824a9cf31a32825c0f6Douglas Gregor  template<>
13ea6c96f63a45b4ffdcdf9824a9cf31a32825c0f6Douglas Gregor  struct count<> {
14ea6c96f63a45b4ffdcdf9824a9cf31a32825c0f6Douglas Gregor    static const unsigned value = 0;
15ea6c96f63a45b4ffdcdf9824a9cf31a32825c0f6Douglas Gregor  };
16ea6c96f63a45b4ffdcdf9824a9cf31a32825c0f6Douglas Gregor
17ea6c96f63a45b4ffdcdf9824a9cf31a32825c0f6Douglas Gregor  template<unsigned> struct unsigned_c { };
18ea6c96f63a45b4ffdcdf9824a9cf31a32825c0f6Douglas Gregor
19ea6c96f63a45b4ffdcdf9824a9cf31a32825c0f6Douglas Gregor  template<typename ... Types>
20ea6c96f63a45b4ffdcdf9824a9cf31a32825c0f6Douglas Gregor  unsigned_c<count<Types...>::value> f();
21ea6c96f63a45b4ffdcdf9824a9cf31a32825c0f6Douglas Gregor
22ea6c96f63a45b4ffdcdf9824a9cf31a32825c0f6Douglas Gregor  void test_f() {
23ea6c96f63a45b4ffdcdf9824a9cf31a32825c0f6Douglas Gregor    unsigned_c<0> uc0a = f(); // okay, deduced to an empty pack
24ea6c96f63a45b4ffdcdf9824a9cf31a32825c0f6Douglas Gregor    unsigned_c<0> uc0b = f<>();
25ea6c96f63a45b4ffdcdf9824a9cf31a32825c0f6Douglas Gregor    unsigned_c<1> uc1 = f<int>();
26ea6c96f63a45b4ffdcdf9824a9cf31a32825c0f6Douglas Gregor    unsigned_c<2> uc2 = f<float, double>();
27ea6c96f63a45b4ffdcdf9824a9cf31a32825c0f6Douglas Gregor  }
28ea6c96f63a45b4ffdcdf9824a9cf31a32825c0f6Douglas Gregor}
2922eaced5cac3cf0522c953f593419fc6cf184aafDouglas Gregor
3022eaced5cac3cf0522c953f593419fc6cf184aafDouglas Gregornamespace rdar12176336 {
3122eaced5cac3cf0522c953f593419fc6cf184aafDouglas Gregor  typedef void (*vararg_func)(...);
3222eaced5cac3cf0522c953f593419fc6cf184aafDouglas Gregor
3322eaced5cac3cf0522c953f593419fc6cf184aafDouglas Gregor  struct method {
3422eaced5cac3cf0522c953f593419fc6cf184aafDouglas Gregor    vararg_func implementation;
3522eaced5cac3cf0522c953f593419fc6cf184aafDouglas Gregor
3622eaced5cac3cf0522c953f593419fc6cf184aafDouglas Gregor    method(vararg_func implementation) : implementation(implementation) {}
3722eaced5cac3cf0522c953f593419fc6cf184aafDouglas Gregor
3822eaced5cac3cf0522c953f593419fc6cf184aafDouglas Gregor    template<typename TReturnType, typename... TArguments, typename TFunctionType = TReturnType (*)(TArguments...)>
3922eaced5cac3cf0522c953f593419fc6cf184aafDouglas Gregor    auto getImplementation() const -> TFunctionType
4022eaced5cac3cf0522c953f593419fc6cf184aafDouglas Gregor    {
4122eaced5cac3cf0522c953f593419fc6cf184aafDouglas Gregor      return reinterpret_cast<TFunctionType>(implementation);
4222eaced5cac3cf0522c953f593419fc6cf184aafDouglas Gregor    }
4322eaced5cac3cf0522c953f593419fc6cf184aafDouglas Gregor  };
4422eaced5cac3cf0522c953f593419fc6cf184aafDouglas Gregor
4522eaced5cac3cf0522c953f593419fc6cf184aafDouglas Gregor  void f() {
4622eaced5cac3cf0522c953f593419fc6cf184aafDouglas Gregor    method m(nullptr);
4722eaced5cac3cf0522c953f593419fc6cf184aafDouglas Gregor    auto imp = m.getImplementation<int, int, int>();
4822eaced5cac3cf0522c953f593419fc6cf184aafDouglas Gregor  }
4922eaced5cac3cf0522c953f593419fc6cf184aafDouglas Gregor}
50