aboutsummaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
Diffstat (limited to 'lib')
-rw-r--r--lib/AST/DeclCXX.cpp23
-rw-r--r--lib/Sema/SemaDecl.cpp17
-rw-r--r--lib/Sema/SemaDeclCXX.cpp9
3 files changed, 42 insertions, 7 deletions
diff --git a/lib/AST/DeclCXX.cpp b/lib/AST/DeclCXX.cpp
index f49b207b0c..cf59d1af36 100644
--- a/lib/AST/DeclCXX.cpp
+++ b/lib/AST/DeclCXX.cpp
@@ -50,6 +50,11 @@ void CXXRecordDecl::Destroy(ASTContext &C) {
void
CXXRecordDecl::setBases(CXXBaseSpecifier const * const *Bases,
unsigned NumBases) {
+ // C++ [dcl.init.aggr]p1:
+ // An aggregate is an array or a class (clause 9) with [...]
+ // no base classes [...].
+ Aggregate = false;
+
if (this->Bases)
delete [] this->Bases;
@@ -78,6 +83,11 @@ CXXRecordDecl::addConstructor(ASTContext &Context,
// Note that we have a user-declared constructor.
UserDeclaredConstructor = true;
+ // C++ [dcl.init.aggr]p1:
+ // An aggregate is an array or a class (clause 9) with no
+ // user-declared constructors (12.1) [...].
+ Aggregate = false;
+
// Note when we have a user-declared copy constructor, which will
// suppress the implicit declaration of a copy constructor.
if (ConDecl->isCopyConstructor(Context))
@@ -154,9 +164,8 @@ CXXConstructorDecl::Create(ASTContext &C, CXXRecordDecl *RD,
bool CXXConstructorDecl::isDefaultConstructor() const {
// C++ [class.ctor]p5:
- //
- // A default constructor for a class X is a constructor of class
- // X that can be called without an argument.
+ // A default constructor for a class X is a constructor of class
+ // X that can be called without an argument.
return (getNumParams() == 0) ||
(getNumParams() > 0 && getParamDecl(0)->getDefaultArg() != 0);
}
@@ -165,10 +174,10 @@ bool
CXXConstructorDecl::isCopyConstructor(ASTContext &Context,
unsigned &TypeQuals) const {
// C++ [class.copy]p2:
- // A non-template constructor for class X is a copy constructor
- // if its first parameter is of type X&, const X&, volatile X& or
- // const volatile X&, and either there are no other parameters
- // or else all other parameters have default arguments (8.3.6).
+ // A non-template constructor for class X is a copy constructor
+ // if its first parameter is of type X&, const X&, volatile X& or
+ // const volatile X&, and either there are no other parameters
+ // or else all other parameters have default arguments (8.3.6).
if ((getNumParams() < 1) ||
(getNumParams() > 1 && getParamDecl(1)->getDefaultArg() == 0))
return false;
diff --git a/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp
index 5dc571c0ee..c8c253a3fb 100644
--- a/lib/Sema/SemaDecl.cpp
+++ b/lib/Sema/SemaDecl.cpp
@@ -701,6 +701,23 @@ bool Sema::CheckInitializerTypes(Expr *&Init, QualType &DeclType,
Init->getSourceRange());
return CheckSingleInitializer(Init, DeclType);
+ } else if (getLangOptions().CPlusPlus) {
+ // C++ [dcl.init]p14:
+ // [...] If the class is an aggregate (8.5.1), and the initializer
+ // is a brace-enclosed list, see 8.5.1.
+ //
+ // Note: 8.5.1 is handled below; here, we diagnose the case where
+ // we have an initializer list and a destination type that is not
+ // an aggregate.
+ // FIXME: In C++0x, this is yet another form of initialization.
+ if (const RecordType *ClassRec = DeclType->getAsRecordType()) {
+ const CXXRecordDecl *ClassDecl = cast<CXXRecordDecl>(ClassRec->getDecl());
+ if (!ClassDecl->isAggregate())
+ return Diag(InitLoc,
+ diag::err_init_non_aggr_init_list,
+ DeclType.getAsString(),
+ Init->getSourceRange());
+ }
}
InitListChecker CheckInitList(this, InitList, DeclType);
diff --git a/lib/Sema/SemaDeclCXX.cpp b/lib/Sema/SemaDeclCXX.cpp
index b95ebf0bad..53051ff57f 100644
--- a/lib/Sema/SemaDeclCXX.cpp
+++ b/lib/Sema/SemaDeclCXX.cpp
@@ -461,6 +461,15 @@ Sema::ActOnCXXMemberDeclarator(Scope *S, AccessSpecifier AS, Declarator &D,
// member decls.
CXXClassMemberWrapper(Member).setAccess(AS);
+ // C++ [dcl.init.aggr]p1:
+ // An aggregate is an array or a class (clause 9) with [...] no
+ // private or protected non-static data members (clause 11).
+ if (isInstField && (AS == AS_private || AS == AS_protected))
+ cast<CXXRecordDecl>(CurContext)->setAggregate(false);
+
+ // FIXME: If the member is a virtual function, mark it its class as
+ // a non-aggregate.
+
if (BitWidth) {
// C++ 9.6p2: Only when declaring an unnamed bit-field may the
// constant-expression be a value equal to zero.