2009-12-16 04:14:24 +08:00
// RUN: %clang_cc1 -fsyntax-only -verify %s
2009-05-28 01:07:49 +08:00
namespace N {
struct Outer {
struct Inner {
template < typename T >
struct InnerTemplate {
struct VeryInner {
typedef T type ;
static enum K1 { K1Val = sizeof ( T ) } Kind1 ;
2009-05-28 01:20:35 +08:00
static enum { K2Val = sizeof ( T ) * 2 } Kind2 ;
2009-05-28 01:30:49 +08:00
enum { K3Val = sizeof ( T ) * 2 } Kind3 ;
2009-05-28 01:07:49 +08:00
void foo ( ) {
K1 k1 = K1Val ;
Kind1 = K1Val ;
Outer : : Inner : : InnerTemplate < type > : : VeryInner : : Kind2 = K2Val ;
2009-05-28 01:30:49 +08:00
Kind3 = K3Val ;
2009-05-28 01:07:49 +08:00
}
2009-05-28 01:30:49 +08:00
struct UeberInner {
void bar ( ) {
K1 k1 = K1Val ;
Kind1 = K1Val ;
Outer : : Inner : : InnerTemplate < type > : : VeryInner : : Kind2 = K2Val ;
2009-05-28 01:54:46 +08:00
InnerTemplate t ;
InnerTemplate < type > t2 ;
2009-05-28 01:30:49 +08:00
}
} ;
2009-05-28 01:07:49 +08:00
} ;
} ;
} ;
} ;
}
typedef int INT ;
template struct N : : Outer : : Inner : : InnerTemplate < INT > : : VeryInner ;
2010-04-01 07:17:41 +08:00
template struct N : : Outer : : Inner : : InnerTemplate < INT > : : UeberInner ; // expected-error{{no struct named 'UeberInner' in 'N::Outer::Inner::InnerTemplate<int>'}}
2009-05-28 07:11:45 +08:00
namespace N2 {
struct Outer2 {
2009-05-29 22:25:00 +08:00
template < typename T , typename U = T >
2009-05-28 07:11:45 +08:00
struct Inner {
void foo ( ) {
enum { K1Val = sizeof ( T ) } k1 ;
2009-05-29 22:25:00 +08:00
enum K2 { K2Val = sizeof ( T ) * 2 } k2a ;
2009-05-28 07:11:45 +08:00
2009-05-29 22:25:00 +08:00
K2 k2b = K2Val ;
struct S { T x , y ; } s1 ;
struct { U x , y ; } s2 ;
s1 . x = s2 . x ; // expected-error{{incompatible}}
typedef T type ;
type t2 = s1 . x ;
2009-05-28 07:11:45 +08:00
2009-05-29 22:26:40 +08:00
typedef struct { T z ; } type2 ;
type2 t3 = { s1 . x } ;
2009-05-28 07:11:45 +08:00
Inner i1 ;
i1 . foo ( ) ;
Inner < T > i2 ;
i2 . foo ( ) ;
}
} ;
} ;
}
2009-05-29 22:25:00 +08:00
template struct N2 : : Outer2 : : Inner < float > ;
template struct N2 : : Outer2 : : Inner < int * , float * > ; // expected-note{{instantiation}}
2009-11-04 15:01:15 +08:00
// Test dependent pointer-to-member expressions.
template < typename T >
struct smart_ptr {
struct safe_bool {
int member ;
} ;
operator int safe_bool : : * ( ) const {
return ptr ? & safe_bool : : member : 0 ;
}
T * ptr ;
} ;
void test_smart_ptr ( smart_ptr < int > p ) {
if ( p ) { }
}
2010-02-06 09:50:47 +08:00
// PR5517
namespace test0 {
template < int K > struct X {
X ( ) { extern void x ( ) ; }
} ;
void g ( ) { X < 2 > ( ) ; }
}
2010-08-18 05:27:17 +08:00
// <rdar://problem/8302161>
namespace test1 {
template < typename T > void f ( T const & t ) {
union { char c ; T t_ ; } ;
c = ' a ' ; // <- this shouldn't silently fail to instantiate
T : : foo ( ) ; // expected-error {{has no members}}
}
template void f ( int const & ) ; // expected-note {{requested here}}
}
Implement DR1330 in C++11 mode, to support libstdc++4.7 which uses it.
We have a new flavor of exception specification, EST_Uninstantiated. A function
type with this exception specification carries a pointer to a FunctionDecl, and
the exception specification for that FunctionDecl is instantiated (if needed)
and used in the place of the function type's exception specification.
When a function template declaration with a non-trivial exception specification
is instantiated, the specialization's exception specification is set to this
new 'uninstantiated' kind rather than being instantiated immediately.
Expr::CanThrow has migrated onto Sema, so it can instantiate exception specs
on-demand. Also, any odr-use of a function triggers the instantiation of its
exception specification (the exception specification could be needed by IRGen).
In passing, fix two places where a DeclRefExpr was created but the corresponding
function was not actually marked odr-used. We used to get away with this, but
don't any more.
Also fix a bug where instantiating an exception specification which refers to
function parameters resulted in a crash. We still have the same bug in default
arguments, which I'll be looking into next.
This, plus a tiny patch to fix libstdc++'s common_type, is enough for clang to
parse (and, in very limited testing, support) all of libstdc++4.7's standard
headers.
llvm-svn: 154886
2012-04-17 08:58:00 +08:00
namespace test2 {
template < typename T > void f ( ) {
T : : error ; // expected-error {{no member}}
}
void g ( ) {
// This counts as an odr-use, so should trigger the instantiation of f<int>.
( void ) & f < int > ; // expected-note {{here}}
}
}