2009-12-16 04:14:24 +08:00
|
|
|
// RUN: %clang_cc1 -fsyntax-only -verify %s
|
2009-05-21 19:50:50 +08:00
|
|
|
struct A {
|
|
|
|
};
|
|
|
|
|
|
|
|
struct ConvertibleToA {
|
|
|
|
operator A();
|
|
|
|
};
|
|
|
|
|
|
|
|
struct ConvertibleToConstA {
|
|
|
|
operator const A();
|
|
|
|
};
|
|
|
|
|
|
|
|
struct B {
|
2009-10-01 05:46:01 +08:00
|
|
|
B& operator=(B&); // expected-note 4 {{candidate function}}
|
2009-05-21 19:50:50 +08:00
|
|
|
};
|
|
|
|
|
|
|
|
struct ConvertibleToB {
|
|
|
|
operator B();
|
|
|
|
};
|
|
|
|
|
|
|
|
struct ConvertibleToBref {
|
|
|
|
operator B&();
|
|
|
|
};
|
|
|
|
|
|
|
|
struct ConvertibleToConstB {
|
|
|
|
operator const B();
|
|
|
|
};
|
|
|
|
|
|
|
|
struct ConvertibleToConstBref {
|
|
|
|
operator const B&();
|
|
|
|
};
|
|
|
|
|
|
|
|
struct C {
|
|
|
|
int operator=(int); // expected-note{{candidate function}}
|
|
|
|
long operator=(long); // expected-note{{candidate function}}
|
|
|
|
int operator+=(int); // expected-note{{candidate function}}
|
|
|
|
int operator+=(long); // expected-note{{candidate function}}
|
|
|
|
};
|
|
|
|
|
|
|
|
struct D {
|
|
|
|
D& operator+=(const D &);
|
|
|
|
};
|
|
|
|
|
|
|
|
struct ConvertibleToInt {
|
|
|
|
operator int();
|
|
|
|
};
|
|
|
|
|
|
|
|
void test() {
|
|
|
|
A a, na;
|
Rework base and member initialization in constructors, with several
(necessarily simultaneous) changes:
- CXXBaseOrMemberInitializer now contains only a single initializer
rather than a set of initialiation arguments + a constructor. The
single initializer covers all aspects of initialization, including
constructor calls as necessary but also cleanup of temporaries
created by the initializer (which we never handled
before!).
- Rework + simplify code generation for CXXBaseOrMemberInitializers,
since we can now just emit the initializer as an initializer.
- Switched base and member initialization over to the new
initialization code (InitializationSequence), so that it
- Improved diagnostics for the new initialization code when
initializing bases and members, to match the diagnostics produced
by the previous (special-purpose) code.
- Simplify the representation of type-checked constructor initializers in
templates; instead of keeping the fully-type-checked AST, which is
rather hard to undo at template instantiation time, throw away the
type-checked AST and store the raw expressions in the AST. This
simplifies instantiation, but loses a little but of information in
the AST.
- When type-checking implicit base or member initializers within a
dependent context, don't add the generated initializers into the
AST, because they'll look like they were explicit.
- Record in CXXConstructExpr when the constructor call is to
initialize a base class, so that CodeGen does not have to infer it
from context. This ensures that we call the right kind of
constructor.
There are also a few "opportunity" fixes here that were needed to not
regress, for example:
- Diagnose default-initialization of a const-qualified class that
does not have a user-declared default constructor. We had this
diagnostic specifically for bases and members, but missed it for
variables. That's fixed now.
- When defining the implicit constructors, destructor, and
copy-assignment operator, set the CurContext to that constructor
when we're defining the body.
llvm-svn: 94952
2010-01-31 17:12:51 +08:00
|
|
|
const A constA = A();
|
2009-05-21 19:50:50 +08:00
|
|
|
ConvertibleToA convertibleToA;
|
|
|
|
ConvertibleToConstA convertibleToConstA;
|
|
|
|
|
|
|
|
B b, nb;
|
Rework base and member initialization in constructors, with several
(necessarily simultaneous) changes:
- CXXBaseOrMemberInitializer now contains only a single initializer
rather than a set of initialiation arguments + a constructor. The
single initializer covers all aspects of initialization, including
constructor calls as necessary but also cleanup of temporaries
created by the initializer (which we never handled
before!).
- Rework + simplify code generation for CXXBaseOrMemberInitializers,
since we can now just emit the initializer as an initializer.
- Switched base and member initialization over to the new
initialization code (InitializationSequence), so that it
- Improved diagnostics for the new initialization code when
initializing bases and members, to match the diagnostics produced
by the previous (special-purpose) code.
- Simplify the representation of type-checked constructor initializers in
templates; instead of keeping the fully-type-checked AST, which is
rather hard to undo at template instantiation time, throw away the
type-checked AST and store the raw expressions in the AST. This
simplifies instantiation, but loses a little but of information in
the AST.
- When type-checking implicit base or member initializers within a
dependent context, don't add the generated initializers into the
AST, because they'll look like they were explicit.
- Record in CXXConstructExpr when the constructor call is to
initialize a base class, so that CodeGen does not have to infer it
from context. This ensures that we call the right kind of
constructor.
There are also a few "opportunity" fixes here that were needed to not
regress, for example:
- Diagnose default-initialization of a const-qualified class that
does not have a user-declared default constructor. We had this
diagnostic specifically for bases and members, but missed it for
variables. That's fixed now.
- When defining the implicit constructors, destructor, and
copy-assignment operator, set the CurContext to that constructor
when we're defining the body.
llvm-svn: 94952
2010-01-31 17:12:51 +08:00
|
|
|
const B constB = B();
|
2009-05-21 19:50:50 +08:00
|
|
|
ConvertibleToB convertibleToB;
|
|
|
|
ConvertibleToBref convertibleToBref;
|
|
|
|
ConvertibleToConstB convertibleToConstB;
|
|
|
|
ConvertibleToConstBref convertibleToConstBref;
|
|
|
|
|
|
|
|
C c, nc;
|
Rework base and member initialization in constructors, with several
(necessarily simultaneous) changes:
- CXXBaseOrMemberInitializer now contains only a single initializer
rather than a set of initialiation arguments + a constructor. The
single initializer covers all aspects of initialization, including
constructor calls as necessary but also cleanup of temporaries
created by the initializer (which we never handled
before!).
- Rework + simplify code generation for CXXBaseOrMemberInitializers,
since we can now just emit the initializer as an initializer.
- Switched base and member initialization over to the new
initialization code (InitializationSequence), so that it
- Improved diagnostics for the new initialization code when
initializing bases and members, to match the diagnostics produced
by the previous (special-purpose) code.
- Simplify the representation of type-checked constructor initializers in
templates; instead of keeping the fully-type-checked AST, which is
rather hard to undo at template instantiation time, throw away the
type-checked AST and store the raw expressions in the AST. This
simplifies instantiation, but loses a little but of information in
the AST.
- When type-checking implicit base or member initializers within a
dependent context, don't add the generated initializers into the
AST, because they'll look like they were explicit.
- Record in CXXConstructExpr when the constructor call is to
initialize a base class, so that CodeGen does not have to infer it
from context. This ensures that we call the right kind of
constructor.
There are also a few "opportunity" fixes here that were needed to not
regress, for example:
- Diagnose default-initialization of a const-qualified class that
does not have a user-declared default constructor. We had this
diagnostic specifically for bases and members, but missed it for
variables. That's fixed now.
- When defining the implicit constructors, destructor, and
copy-assignment operator, set the CurContext to that constructor
when we're defining the body.
llvm-svn: 94952
2010-01-31 17:12:51 +08:00
|
|
|
const C constC = C();
|
2009-05-21 19:50:50 +08:00
|
|
|
|
|
|
|
D d, nd;
|
Rework base and member initialization in constructors, with several
(necessarily simultaneous) changes:
- CXXBaseOrMemberInitializer now contains only a single initializer
rather than a set of initialiation arguments + a constructor. The
single initializer covers all aspects of initialization, including
constructor calls as necessary but also cleanup of temporaries
created by the initializer (which we never handled
before!).
- Rework + simplify code generation for CXXBaseOrMemberInitializers,
since we can now just emit the initializer as an initializer.
- Switched base and member initialization over to the new
initialization code (InitializationSequence), so that it
- Improved diagnostics for the new initialization code when
initializing bases and members, to match the diagnostics produced
by the previous (special-purpose) code.
- Simplify the representation of type-checked constructor initializers in
templates; instead of keeping the fully-type-checked AST, which is
rather hard to undo at template instantiation time, throw away the
type-checked AST and store the raw expressions in the AST. This
simplifies instantiation, but loses a little but of information in
the AST.
- When type-checking implicit base or member initializers within a
dependent context, don't add the generated initializers into the
AST, because they'll look like they were explicit.
- Record in CXXConstructExpr when the constructor call is to
initialize a base class, so that CodeGen does not have to infer it
from context. This ensures that we call the right kind of
constructor.
There are also a few "opportunity" fixes here that were needed to not
regress, for example:
- Diagnose default-initialization of a const-qualified class that
does not have a user-declared default constructor. We had this
diagnostic specifically for bases and members, but missed it for
variables. That's fixed now.
- When defining the implicit constructors, destructor, and
copy-assignment operator, set the CurContext to that constructor
when we're defining the body.
llvm-svn: 94952
2010-01-31 17:12:51 +08:00
|
|
|
const D constD = D();
|
2009-05-21 19:50:50 +08:00
|
|
|
|
|
|
|
ConvertibleToInt convertibleToInt;
|
|
|
|
|
|
|
|
na = a;
|
|
|
|
na = constA;
|
|
|
|
na = convertibleToA;
|
|
|
|
na = convertibleToConstA;
|
|
|
|
na += a; // expected-error{{no viable overloaded '+='}}
|
|
|
|
|
|
|
|
nb = b;
|
|
|
|
nb = constB; // expected-error{{no viable overloaded '='}}
|
|
|
|
nb = convertibleToB; // expected-error{{no viable overloaded '='}}
|
|
|
|
nb = convertibleToBref;
|
|
|
|
nb = convertibleToConstB; // expected-error{{no viable overloaded '='}}
|
|
|
|
nb = convertibleToConstBref; // expected-error{{no viable overloaded '='}}
|
|
|
|
|
|
|
|
nc = c;
|
|
|
|
nc = constC;
|
|
|
|
nc = 1;
|
|
|
|
nc = 1L;
|
|
|
|
nc = 1.0; // expected-error{{use of overloaded operator '=' is ambiguous}}
|
|
|
|
nc += 1;
|
|
|
|
nc += 1L;
|
|
|
|
nc += 1.0; // expected-error{{use of overloaded operator '+=' is ambiguous}}
|
|
|
|
|
|
|
|
nd = d;
|
|
|
|
nd += d;
|
|
|
|
nd += constD;
|
|
|
|
|
|
|
|
int i;
|
|
|
|
i = convertibleToInt;
|
2010-04-09 08:35:39 +08:00
|
|
|
i = a; // expected-error{{assigning to 'int' from incompatible type 'A'}}
|
2009-05-21 19:50:50 +08:00
|
|
|
}
|
|
|
|
|
2010-08-17 07:42:35 +08:00
|
|
|
// <rdar://problem/8315440>: Don't crash
|
|
|
|
// FIXME: the recovery here is really bad.
|
2010-09-18 09:28:11 +08:00
|
|
|
namespace test1 { // expected-note{{to match this '{'}}
|
|
|
|
template<typename T> class A : public unknown::X { // expected-error {{undeclared identifier 'unknown'}} expected-error {{expected class name}} \
|
|
|
|
// expected-note{{template parameter is declared here}}
|
|
|
|
A(UndeclaredType n) : X(n) {} // expected-error{{expected ')'}} expected-note{{to match this '('}} \
|
|
|
|
// expected-error{{use of undeclared identifier 'n'}}
|
2010-08-17 07:42:35 +08:00
|
|
|
};
|
2010-09-18 09:28:11 +08:00
|
|
|
template<typename T> class B : public A<T> { // expected-error{{declaration of 'T' shadows template parameter}}
|
2010-08-17 07:42:35 +08:00
|
|
|
virtual void foo() {}
|
|
|
|
};
|
2010-09-18 09:28:11 +08:00
|
|
|
extern template class A<char>; // expected-error{{expected member name or ';' after declaration specifiers}}
|
|
|
|
extern template class B<char>; // expected-error{{expected member name or ';' after declaration specifiers}}
|
|
|
|
} // expected-error{{expected ';' after class}} // expected-error{{expected '}'}}
|