/* Template argument tests.
   Copyright 2010-2023 Free Software Foundation, Inc.
   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 3 of the License, or
   (at your option) any later version.
   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.
   You should have received a copy of the GNU General Public License
   along with this program.  If not, see .
   Please email any bugs, comments, and/or additions to this file to:
   bug-gdb@gnu.org  */
int a_global;
struct S
{
  int f;
  void somefunc() { }
};
template
struct Base
{
  template
  struct Inner
  {
    void inner_m ()
    {
      // Breakpoint 2.
    }
  };
  void base_m ()
  {
    // Breakpoint 1.
  }
  template
  void templ_m ()
  {
    // Breakpoint 4.
  }
};
template
void func ()
{
  // Breakpoint 3.
}
template
struct K2
{
  void k2_m ()
  {
    // Breakpoint 5.
  }
};
// GCC PR debug/49546
struct S3
{
  static void m (int x) {}
};
template 
// or: template 
struct K3
{
  void k3_m ()
  {
    F (0);	// Breakpoint 6.
  }
};
namespace pr24470
{
// From PR c++/24470
// This caused a gdb crash during startup.
template  struct b {};
template  struct c {
  template  using e = b;
  void k(e<0>);
};
template  class, unsigned long...>
struct m;
template  class h, unsigned long i>
struct m {
  using j = b;
};
struct n {
  template  using f = typename m::j;
};
n::f l;
}
int main ()
{
  Base base;
  // Note that instantiating with P==0 does not work with g++.
  // That would be worth testing, once g++ is fixed.
  Base::Inner inner;
  K2<&S::somefunc> k2;
  K3<&S3::m> k3;
// or: K3 k3;
  base.base_m ();
  inner.inner_m ();
  func ();
  base.templ_m ();
  k2.k2_m ();
  k3.k3_m ();
  return 0;
}