diff options
Diffstat (limited to 'clang/lib')
| -rw-r--r-- | clang/lib/AST/DeclCXX.cpp | 19 | ||||
| -rw-r--r-- | clang/lib/Sema/Sema.h | 5 | ||||
| -rw-r--r-- | clang/lib/Sema/SemaDeclCXX.cpp | 35 | 
3 files changed, 46 insertions, 13 deletions
diff --git a/clang/lib/AST/DeclCXX.cpp b/clang/lib/AST/DeclCXX.cpp index 0f2230116cc..7b5a29028c4 100644 --- a/clang/lib/AST/DeclCXX.cpp +++ b/clang/lib/AST/DeclCXX.cpp @@ -564,9 +564,11 @@ CXXDestructorDecl::computeBaseOrMembersToDestroy(ASTContext &C) {  void  CXXConstructorDecl::setBaseOrMemberInitializers( -                                    ASTContext &C, -                                    CXXBaseOrMemberInitializer **Initializers, -                                    unsigned NumInitializers) { +                                ASTContext &C, +                                CXXBaseOrMemberInitializer **Initializers, +                                unsigned NumInitializers, +                                llvm::SmallVectorImpl<CXXBaseSpecifier *>& Bases,           +                                llvm::SmallVectorImpl<FieldDecl *>&Fields) {    // We need to build the initializer AST according to order of construction    // and not what user specified in the Initializers list.    CXXRecordDecl *ClassDecl = cast<CXXRecordDecl>(getDeclContext()); @@ -594,7 +596,9 @@ CXXConstructorDecl::setBaseOrMemberInitializers(        CXXRecordDecl *VBaseDecl =           cast<CXXRecordDecl>(VBase->getType()->getAsRecordType()->getDecl());        assert(VBaseDecl && "setBaseOrMemberInitializers - VBaseDecl null"); -      // FIXME. Issue error if default ctor is missing. +      if (!VBaseDecl->getDefaultConstructor(C) &&  +          !VBase->getType()->isDependentType()) +        Bases.push_back(VBase);        CXXBaseOrMemberInitializer *Member =           new (C) CXXBaseOrMemberInitializer(VBase->getType(), 0, 0,                                             VBaseDecl->getDefaultConstructor(C), @@ -617,7 +621,9 @@ CXXConstructorDecl::setBaseOrMemberInitializers(        CXXRecordDecl *BaseDecl =           cast<CXXRecordDecl>(Base->getType()->getAsRecordType()->getDecl());        assert(BaseDecl && "setBaseOrMemberInitializers - BaseDecl null"); -      // FIXME. Issue error if default ctor is missing. +      if (!BaseDecl->getDefaultConstructor(C) &&  +          !Base->getType()->isDependentType()) +        Bases.push_back(Base);        CXXBaseOrMemberInitializer *Member =         new (C) CXXBaseOrMemberInitializer(Base->getType(), 0, 0,                                           BaseDecl->getDefaultConstructor(C), @@ -643,7 +649,8 @@ CXXConstructorDecl::setBaseOrMemberInitializers(        if (CXXRecordDecl *FieldClassDecl =               dyn_cast<CXXRecordDecl>(FieldType->getAsRecordType()->getDecl()))          Ctor = FieldClassDecl->getDefaultConstructor(C); -      // FIXME. Issue error if default ctor is missing. +      if (!Ctor && !FieldType->isDependentType()) +        Fields.push_back(*Field);        CXXBaseOrMemberInitializer *Member =           new (C) CXXBaseOrMemberInitializer((*Field), 0, 0,                                             Ctor, diff --git a/clang/lib/Sema/Sema.h b/clang/lib/Sema/Sema.h index d66e642af3a..5f504384454 100644 --- a/clang/lib/Sema/Sema.h +++ b/clang/lib/Sema/Sema.h @@ -1482,6 +1482,11 @@ public:                                 const FunctionProtoType *Proto,                                 Expr **Args, unsigned NumArgs,                                 SourceLocation RParenLoc); +  void BuildBaseOrMemberInitializers(ASTContext &C, +                                 CXXConstructorDecl *Constructor, +                                 CXXBaseOrMemberInitializer **Initializers, +                                 unsigned NumInitializers +                                 );    /// ActOnCallExpr - Handle a call to Fn with the specified array of arguments.    /// This provides the location of the left/right parens and a list of comma diff --git a/clang/lib/Sema/SemaDeclCXX.cpp b/clang/lib/Sema/SemaDeclCXX.cpp index c12878c7603..d5c8c3d3fce 100644 --- a/clang/lib/Sema/SemaDeclCXX.cpp +++ b/clang/lib/Sema/SemaDeclCXX.cpp @@ -810,6 +810,26 @@ Sema::ActOnMemInitializer(DeclPtrTy ConstructorD,                                                    NumArgs, C, IdLoc);  } +void +Sema::BuildBaseOrMemberInitializers(ASTContext &C, +                                 CXXConstructorDecl *Constructor, +                                 CXXBaseOrMemberInitializer **Initializers, +                                 unsigned NumInitializers +                                 ) { +  llvm::SmallVector<CXXBaseSpecifier *, 4>Bases; +  llvm::SmallVector<FieldDecl *, 4>Members; +   +  Constructor->setBaseOrMemberInitializers(C,  +                                           Initializers, NumInitializers, +                                           Bases, Members); +  for (unsigned int i = 0; i < Bases.size(); i++) +    Diag(Bases[i]->getSourceRange().getBegin(),  +         diag::err_missing_default_constructor) << 0 << Bases[i]->getType(); +  for (unsigned int i = 0; i < Members.size(); i++) +    Diag(Members[i]->getLocation(), diag::err_missing_default_constructor)  +          << 1 << Members[i]->getType(); +} +  static void *GetKeyForTopLevelField(FieldDecl *Field) {    // For anonymous unions, use the class declaration as the key.    if (const RecordType *RT = Field->getType()->getAsRecordType()) { @@ -872,11 +892,11 @@ void Sema::ActOnMemInitializers(DeclPtrTy ConstructorDecl,        << 0;      err = true;    } -  if (!err) { -    Constructor->setBaseOrMemberInitializers(Context,  -                    reinterpret_cast<CXXBaseOrMemberInitializer **>(MemInits),  -                    NumMemInits); -  } +  if (!err) +    BuildBaseOrMemberInitializers(Context, Constructor, +                      reinterpret_cast<CXXBaseOrMemberInitializer **>(MemInits),  +                      NumMemInits); +      if (!err && (Diags.getDiagnosticLevel(diag::warn_base_initialized)                 != Diagnostic::Ignored ||                 Diags.getDiagnosticLevel(diag::warn_field_initialized) @@ -960,8 +980,9 @@ void Sema::ActOnDefaultCtorInitializers(DeclPtrTy CDtorDecl) {    if (CXXConstructorDecl *Constructor         = dyn_cast<CXXConstructorDecl>(CDtorDecl.getAs<Decl>())) -    Constructor->setBaseOrMemberInitializers(Context,  -                                           (CXXBaseOrMemberInitializer **)0, 0); +    BuildBaseOrMemberInitializers(Context, +                                     Constructor, +                                     (CXXBaseOrMemberInitializer **)0, 0);  }  namespace {  | 

