11b59e9c3e1780567e30e5ead2b3512f0aa21fcb6Douglas Gregor// RUN: %clang_cc1 %s -ast-print -o - -chain-include %s -chain-include %s
21b59e9c3e1780567e30e5ead2b3512f0aa21fcb6Douglas Gregor
31b59e9c3e1780567e30e5ead2b3512f0aa21fcb6Douglas Gregor#if !defined(PASS1)
41b59e9c3e1780567e30e5ead2b3512f0aa21fcb6Douglas Gregor#define PASS1
51b59e9c3e1780567e30e5ead2b3512f0aa21fcb6Douglas Gregor
61b59e9c3e1780567e30e5ead2b3512f0aa21fcb6Douglas Gregortemplate <class T> class TClass;
71b59e9c3e1780567e30e5ead2b3512f0aa21fcb6Douglas Gregor
81b59e9c3e1780567e30e5ead2b3512f0aa21fcb6Douglas Gregornamespace NS {
91b59e9c3e1780567e30e5ead2b3512f0aa21fcb6Douglas Gregor    template <class X, class Y> TClass<X> problematic(X * ptr, const TClass<Y> &src);
101b59e9c3e1780567e30e5ead2b3512f0aa21fcb6Douglas Gregor
111b59e9c3e1780567e30e5ead2b3512f0aa21fcb6Douglas Gregor    template <class T>
121b59e9c3e1780567e30e5ead2b3512f0aa21fcb6Douglas Gregor    class TBaseClass
131b59e9c3e1780567e30e5ead2b3512f0aa21fcb6Douglas Gregor    {
141b59e9c3e1780567e30e5ead2b3512f0aa21fcb6Douglas Gregor    protected:
151b59e9c3e1780567e30e5ead2b3512f0aa21fcb6Douglas Gregor        template <class X, class Y> friend TClass<X> problematic(X * ptr, const TClass<Y> &src);
161b59e9c3e1780567e30e5ead2b3512f0aa21fcb6Douglas Gregor    };
171b59e9c3e1780567e30e5ead2b3512f0aa21fcb6Douglas Gregor}
181b59e9c3e1780567e30e5ead2b3512f0aa21fcb6Douglas Gregor
191b59e9c3e1780567e30e5ead2b3512f0aa21fcb6Douglas Gregortemplate <class T>
201b59e9c3e1780567e30e5ead2b3512f0aa21fcb6Douglas Gregorclass TClass: public NS::TBaseClass<T>
211b59e9c3e1780567e30e5ead2b3512f0aa21fcb6Douglas Gregor{
221b59e9c3e1780567e30e5ead2b3512f0aa21fcb6Douglas Gregorpublic:
231b59e9c3e1780567e30e5ead2b3512f0aa21fcb6Douglas Gregor    inline TClass() { }
241b59e9c3e1780567e30e5ead2b3512f0aa21fcb6Douglas Gregor};
251b59e9c3e1780567e30e5ead2b3512f0aa21fcb6Douglas Gregor
261b59e9c3e1780567e30e5ead2b3512f0aa21fcb6Douglas Gregor
271b59e9c3e1780567e30e5ead2b3512f0aa21fcb6Douglas Gregornamespace NS {
281b59e9c3e1780567e30e5ead2b3512f0aa21fcb6Douglas Gregor    template <class X, class T>
291b59e9c3e1780567e30e5ead2b3512f0aa21fcb6Douglas Gregor    TClass<X> problematic(X *ptr, const TClass<T> &src);
301b59e9c3e1780567e30e5ead2b3512f0aa21fcb6Douglas Gregor}
311b59e9c3e1780567e30e5ead2b3512f0aa21fcb6Douglas Gregor
321b59e9c3e1780567e30e5ead2b3512f0aa21fcb6Douglas Gregortemplate <class X, class T>
331b59e9c3e1780567e30e5ead2b3512f0aa21fcb6Douglas GregorTClass<X> unconst(const TClass<T> &src);
341b59e9c3e1780567e30e5ead2b3512f0aa21fcb6Douglas Gregor
351b59e9c3e1780567e30e5ead2b3512f0aa21fcb6Douglas Gregor#elif !defined(PASS2)
361b59e9c3e1780567e30e5ead2b3512f0aa21fcb6Douglas Gregor#define PASS2
371b59e9c3e1780567e30e5ead2b3512f0aa21fcb6Douglas Gregor
381b59e9c3e1780567e30e5ead2b3512f0aa21fcb6Douglas Gregornamespace std {
391b59e9c3e1780567e30e5ead2b3512f0aa21fcb6Douglas Gregorclass s {};
401b59e9c3e1780567e30e5ead2b3512f0aa21fcb6Douglas Gregor}
411b59e9c3e1780567e30e5ead2b3512f0aa21fcb6Douglas Gregor
421b59e9c3e1780567e30e5ead2b3512f0aa21fcb6Douglas Gregor
431b59e9c3e1780567e30e5ead2b3512f0aa21fcb6Douglas Gregortypedef TClass<std::s> TStr;
441b59e9c3e1780567e30e5ead2b3512f0aa21fcb6Douglas Gregor
451b59e9c3e1780567e30e5ead2b3512f0aa21fcb6Douglas Gregorstruct crash {
461b59e9c3e1780567e30e5ead2b3512f0aa21fcb6Douglas Gregor  TStr str;
471b59e9c3e1780567e30e5ead2b3512f0aa21fcb6Douglas Gregor
481b59e9c3e1780567e30e5ead2b3512f0aa21fcb6Douglas Gregor  crash(const TClass<std::s> p)
491b59e9c3e1780567e30e5ead2b3512f0aa21fcb6Douglas Gregor  {
501b59e9c3e1780567e30e5ead2b3512f0aa21fcb6Douglas Gregor    unconst<TStr>(p);
511b59e9c3e1780567e30e5ead2b3512f0aa21fcb6Douglas Gregor  }
521b59e9c3e1780567e30e5ead2b3512f0aa21fcb6Douglas Gregor};
531b59e9c3e1780567e30e5ead2b3512f0aa21fcb6Douglas Gregor
541b59e9c3e1780567e30e5ead2b3512f0aa21fcb6Douglas Gregor#else
551b59e9c3e1780567e30e5ead2b3512f0aa21fcb6Douglas Gregor
561b59e9c3e1780567e30e5ead2b3512f0aa21fcb6Douglas Gregorvoid f() {
571b59e9c3e1780567e30e5ead2b3512f0aa21fcb6Douglas Gregor    const TStr p;
581b59e9c3e1780567e30e5ead2b3512f0aa21fcb6Douglas Gregor    crash c(p);
591b59e9c3e1780567e30e5ead2b3512f0aa21fcb6Douglas Gregor}
601b59e9c3e1780567e30e5ead2b3512f0aa21fcb6Douglas Gregor
611b59e9c3e1780567e30e5ead2b3512f0aa21fcb6Douglas Gregor#endif
62