diff options
author | Alexis Hunt <alercah@gmail.com> | 2011-06-10 03:50:41 +0000 |
---|---|---|
committer | Alexis Hunt <alercah@gmail.com> | 2011-06-10 03:50:41 +0000 |
commit | eef8ee0c8d8d4d87ce9fcac9ab800f38f672c979 (patch) | |
tree | ce7bde43aecab843edee23f658615183ed1be29d /clang/lib/Sema/SemaDeclCXX.cpp | |
parent | 280ddee8bded79832e101e6874743a487f00bde7 (diff) | |
download | bcm5719-llvm-eef8ee0c8d8d4d87ce9fcac9ab800f38f672c979.tar.gz bcm5719-llvm-eef8ee0c8d8d4d87ce9fcac9ab800f38f672c979.zip |
Implement caching of default constructors on the resolution table. This
isn't yet used for the less controlled environments of initialization.
Also a few random text fixups.
llvm-svn: 132833
Diffstat (limited to 'clang/lib/Sema/SemaDeclCXX.cpp')
-rw-r--r-- | clang/lib/Sema/SemaDeclCXX.cpp | 104 |
1 files changed, 41 insertions, 63 deletions
diff --git a/clang/lib/Sema/SemaDeclCXX.cpp b/clang/lib/Sema/SemaDeclCXX.cpp index 18a73666b38..29e81d3f7f3 100644 --- a/clang/lib/Sema/SemaDeclCXX.cpp +++ b/clang/lib/Sema/SemaDeclCXX.cpp @@ -3318,7 +3318,7 @@ bool Sema::ShouldDeleteDefaultConstructor(CXXConstructorDecl *CD) { // FIXME: We should put some diagnostic logic right into this function. // C++0x [class.ctor]/5 - // A defaulted default constructor for class X is defined as delete if: + // A defaulted default constructor for class X is defined as deleted if: for (CXXRecordDecl::base_class_iterator BI = RD->bases_begin(), BE = RD->bases_end(); @@ -3331,7 +3331,7 @@ bool Sema::ShouldDeleteDefaultConstructor(CXXConstructorDecl *CD) { assert(BaseDecl && "base isn't a CXXRecordDecl"); // -- any [direct base class] has a type with a destructor that is - // delete or inaccessible from the defaulted default constructor + // deleted or inaccessible from the defaulted default constructor CXXDestructorDecl *BaseDtor = LookupDestructor(BaseDecl); if (BaseDtor->isDeleted()) return true; @@ -3343,14 +3343,12 @@ bool Sema::ShouldDeleteDefaultConstructor(CXXConstructorDecl *CD) { // overload resolution as applied to [its] default constructor // results in an ambiguity or in a function that is deleted or // inaccessible from the defaulted default constructor - InitializedEntity BaseEntity = - InitializedEntity::InitializeBase(Context, BI, 0); - InitializationKind Kind = - InitializationKind::CreateDirect(Loc, Loc, Loc); - - InitializationSequence InitSeq(*this, BaseEntity, Kind, 0, 0); + CXXConstructorDecl *BaseDefault = LookupDefaultConstructor(BaseDecl); + if (!BaseDefault || BaseDefault->isDeleted()) + return true; - if (InitSeq.Failed()) + if (CheckConstructorAccess(Loc, BaseDefault, BaseDefault->getAccess(), + PDiag()) != AR_accessible) return true; } @@ -3373,14 +3371,12 @@ bool Sema::ShouldDeleteDefaultConstructor(CXXConstructorDecl *CD) { // overload resolution as applied to [its] default constructor // results in an ambiguity or in a function that is deleted or // inaccessible from the defaulted default constructor - InitializedEntity BaseEntity = - InitializedEntity::InitializeBase(Context, BI, BI); - InitializationKind Kind = - InitializationKind::CreateDirect(Loc, Loc, Loc); - - InitializationSequence InitSeq(*this, BaseEntity, Kind, 0, 0); + CXXConstructorDecl *BaseDefault = LookupDefaultConstructor(BaseDecl); + if (!BaseDefault || BaseDefault->isDeleted()) + return true; - if (InitSeq.Failed()) + if (CheckConstructorAccess(Loc, BaseDefault, BaseDefault->getAccess(), + PDiag()) != AR_accessible) return true; } @@ -3448,22 +3444,24 @@ bool Sema::ShouldDeleteDefaultConstructor(CXXConstructorDecl *CD) { // This is technically non-conformant, but sanity demands it. continue; } + + // -- any non-static data member ... has class type M (or array thereof) + // and either M has no default constructor or overload resolution as + // applied to M's default constructor results in an ambiguity or in a + // function that is deleted or inaccessible from the defaulted default + // constructor. + CXXConstructorDecl *FieldDefault = LookupDefaultConstructor(FieldRecord); + if (!FieldDefault || FieldDefault->isDeleted()) + return true; + if (CheckConstructorAccess(Loc, FieldDefault, FieldDefault->getAccess(), + PDiag()) != AR_accessible) + return true; } else if (!Union && FieldType.isConstQualified()) { // -- any non-variant non-static data member of const-qualified type (or // array thereof) with no brace-or-equal-initializer does not have a // user-provided default constructor return true; } - - InitializedEntity MemberEntity = - InitializedEntity::InitializeMember(*FI, 0); - InitializationKind Kind = - InitializationKind::CreateDirect(Loc, Loc, Loc); - - InitializationSequence InitSeq(*this, MemberEntity, Kind, 0, 0); - - if (InitSeq.Failed()) - return true; } if (Union && AllConst) @@ -3548,7 +3546,7 @@ bool Sema::ShouldDeleteCopyConstructor(CXXConstructorDecl *CD) { CXXRecordDecl *BaseDecl = BaseType->getAsCXXRecordDecl(); assert(BaseDecl && "base isn't a CXXRecordDecl"); - // -- any [direct base class] of a type with a destructor that is deleted or + // -- any [virtual base class] of a type with a destructor that is deleted or // inaccessible from the defaulted constructor CXXDestructorDecl *BaseDtor = LookupDestructor(BaseDecl); if (BaseDtor->isDeleted()) @@ -5895,28 +5893,6 @@ namespace { }; } -static CXXConstructorDecl *getDefaultConstructorUnsafe(Sema &Self, - CXXRecordDecl *D) { - ASTContext &Context = Self.Context; - QualType ClassType = Context.getTypeDeclType(D); - DeclarationName ConstructorName - = Context.DeclarationNames.getCXXConstructorName( - Context.getCanonicalType(ClassType.getUnqualifiedType())); - - DeclContext::lookup_const_iterator Con, ConEnd; - for (llvm::tie(Con, ConEnd) = D->lookup(ConstructorName); - Con != ConEnd; ++Con) { - // FIXME: In C++0x, a constructor template can be a default constructor. - if (isa<FunctionTemplateDecl>(*Con)) - continue; - - CXXConstructorDecl *Constructor = cast<CXXConstructorDecl>(*Con); - if (Constructor->isDefaultConstructor()) - return Constructor; - } - return 0; -} - Sema::ImplicitExceptionSpecification Sema::ComputeDefaultedDefaultCtorExceptionSpec(CXXRecordDecl *ClassDecl) { // C++ [except.spec]p14: @@ -5933,10 +5909,10 @@ Sema::ComputeDefaultedDefaultCtorExceptionSpec(CXXRecordDecl *ClassDecl) { if (const RecordType *BaseType = B->getType()->getAs<RecordType>()) { CXXRecordDecl *BaseClassDecl = cast<CXXRecordDecl>(BaseType->getDecl()); - if (BaseClassDecl->needsImplicitDefaultConstructor()) - ExceptSpec.CalledDecl(DeclareImplicitDefaultConstructor(BaseClassDecl)); - else if (CXXConstructorDecl *Constructor - = getDefaultConstructorUnsafe(*this, BaseClassDecl)) + CXXConstructorDecl *Constructor = LookupDefaultConstructor(BaseClassDecl); + // If this is a deleted function, add it anyway. This might be conformant + // with the standard. This might not. I'm not sure. It might not matter. + if (Constructor) ExceptSpec.CalledDecl(Constructor); } } @@ -5947,10 +5923,10 @@ Sema::ComputeDefaultedDefaultCtorExceptionSpec(CXXRecordDecl *ClassDecl) { B != BEnd; ++B) { if (const RecordType *BaseType = B->getType()->getAs<RecordType>()) { CXXRecordDecl *BaseClassDecl = cast<CXXRecordDecl>(BaseType->getDecl()); - if (BaseClassDecl->needsImplicitDefaultConstructor()) - ExceptSpec.CalledDecl(DeclareImplicitDefaultConstructor(BaseClassDecl)); - else if (CXXConstructorDecl *Constructor - = getDefaultConstructorUnsafe(*this, BaseClassDecl)) + CXXConstructorDecl *Constructor = LookupDefaultConstructor(BaseClassDecl); + // If this is a deleted function, add it anyway. This might be conformant + // with the standard. This might not. I'm not sure. It might not matter. + if (Constructor) ExceptSpec.CalledDecl(Constructor); } } @@ -5961,12 +5937,14 @@ Sema::ComputeDefaultedDefaultCtorExceptionSpec(CXXRecordDecl *ClassDecl) { F != FEnd; ++F) { if (const RecordType *RecordTy = Context.getBaseElementType(F->getType())->getAs<RecordType>()) { - CXXRecordDecl *FieldClassDecl = cast<CXXRecordDecl>(RecordTy->getDecl()); - if (FieldClassDecl->needsImplicitDefaultConstructor()) - ExceptSpec.CalledDecl( - DeclareImplicitDefaultConstructor(FieldClassDecl)); - else if (CXXConstructorDecl *Constructor - = getDefaultConstructorUnsafe(*this, FieldClassDecl)) + CXXRecordDecl *FieldRecDecl = cast<CXXRecordDecl>(RecordTy->getDecl()); + CXXConstructorDecl *Constructor = LookupDefaultConstructor(FieldRecDecl); + // If this is a deleted function, add it anyway. This might be conformant + // with the standard. This might not. I'm not sure. It might not matter. + // In particular, the problem is that this function never gets called. It + // might just be ill-formed because this function attempts to refer to + // a deleted function here. + if (Constructor) ExceptSpec.CalledDecl(Constructor); } } |