2009-12-16 04:14:24 +08:00
|
|
|
// RUN: %clang_cc1 -fsyntax-only -verify %s
|
2009-09-04 03:36:46 +08:00
|
|
|
|
|
|
|
struct A {
|
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
|
|
|
A() : value(), cvalue() { } // expected-error {{reference to type 'int' requires an initializer}}
|
|
|
|
int &value;
|
2009-09-04 03:36:46 +08:00
|
|
|
const int cvalue;
|
|
|
|
};
|
|
|
|
|
|
|
|
struct B {
|
|
|
|
};
|
|
|
|
|
|
|
|
struct X {
|
2010-03-10 19:27:22 +08:00
|
|
|
X() { } // expected-error {{constructor for 'X' must explicitly initialize the reference member 'value'}} \
|
|
|
|
// expected-error {{constructor for 'X' must explicitly initialize the const member 'cvalue'}} \
|
|
|
|
// expected-error {{constructor for 'X' must explicitly initialize the reference member 'b'}} \
|
|
|
|
// expected-error {{constructor for 'X' must explicitly initialize the const member 'cb'}}
|
2010-04-23 10:20:12 +08:00
|
|
|
int &value; // expected-note{{declared here}}
|
|
|
|
const int cvalue; // expected-note{{declared here}}
|
|
|
|
B& b; // expected-note{{declared here}}
|
|
|
|
const B cb; // expected-note{{declared here}}
|
2009-09-04 03:36:46 +08:00
|
|
|
};
|
2009-12-31 11:10:55 +08:00
|
|
|
|
|
|
|
|
|
|
|
// PR5924
|
|
|
|
struct bar {};
|
|
|
|
bar xxx();
|
|
|
|
|
|
|
|
struct foo {
|
|
|
|
foo_t a; // expected-error {{unknown type name 'foo_t'}}
|
|
|
|
foo() : a(xxx()) {} // no error here.
|
|
|
|
};
|