diff options
Diffstat (limited to 'clang/lib')
-rw-r--r-- | clang/lib/AST/DeclCXX.cpp | 14 | ||||
-rw-r--r-- | clang/lib/CodeGen/CGBlocks.cpp | 19 | ||||
-rw-r--r-- | clang/lib/CodeGen/CodeGenModule.cpp | 4 | ||||
-rw-r--r-- | clang/lib/Serialization/ASTReaderDecl.cpp | 1 | ||||
-rw-r--r-- | clang/lib/Serialization/ASTWriter.cpp | 1 |
5 files changed, 19 insertions, 20 deletions
diff --git a/clang/lib/AST/DeclCXX.cpp b/clang/lib/AST/DeclCXX.cpp index f32c85629c5..63fa9a77af0 100644 --- a/clang/lib/AST/DeclCXX.cpp +++ b/clang/lib/AST/DeclCXX.cpp @@ -33,7 +33,7 @@ CXXRecordDecl::DefinitionData::DefinitionData(CXXRecordDecl *D) Aggregate(true), PlainOldData(true), Empty(true), Polymorphic(false), Abstract(false), IsStandardLayout(true), HasNoNonEmptyBases(true), HasPrivateFields(false), HasProtectedFields(false), HasPublicFields(false), - HasTrivialDefaultConstructor(true), + HasMutableFields(false), HasTrivialDefaultConstructor(true), HasConstExprNonCopyMoveConstructor(false), HasTrivialCopyConstructor(true), HasTrivialMoveConstructor(true), HasTrivialCopyAssignment(true), HasTrivialMoveAssignment(true), HasTrivialDestructor(true), @@ -225,6 +225,10 @@ CXXRecordDecl::setBases(CXXBaseSpecifier const * const *Bases, // have trivial destructors. if (!BaseClassDecl->hasTrivialDestructor()) data().HasTrivialDestructor = false; + + // Keep track of the presence of mutable fields. + if (BaseClassDecl->hasMutableFields()) + data().HasMutableFields = true; } if (VBases.empty()) @@ -688,6 +692,10 @@ void CXXRecordDecl::addedMember(Decl *D) { data().HasPublicFields) > 1) data().IsStandardLayout = false; + // Keep track of the presence of mutable fields. + if (Field->isMutable()) + data().HasMutableFields = true; + // C++0x [class]p9: // A POD struct is a class that is both a trivial class and a // standard-layout class, and has no non-static data members of type @@ -779,6 +787,10 @@ void CXXRecordDecl::addedMember(Decl *D) { } } } + + // Keep track of the presence of mutable fields. + if (FieldRec->hasMutableFields()) + data().HasMutableFields = true; } } diff --git a/clang/lib/CodeGen/CGBlocks.cpp b/clang/lib/CodeGen/CGBlocks.cpp index f26d79c0667..c6bedd28460 100644 --- a/clang/lib/CodeGen/CGBlocks.cpp +++ b/clang/lib/CodeGen/CGBlocks.cpp @@ -189,23 +189,6 @@ namespace { } } -/// Determines if the given record type has a mutable field. -static bool hasMutableField(const CXXRecordDecl *record) { - for (CXXRecordDecl::field_iterator - i = record->field_begin(), e = record->field_end(); i != e; ++i) - if ((*i)->isMutable()) - return true; - - for (CXXRecordDecl::base_class_const_iterator - i = record->bases_begin(), e = record->bases_end(); i != e; ++i) { - const RecordType *record = i->getType()->castAs<RecordType>(); - if (hasMutableField(cast<CXXRecordDecl>(record->getDecl()))) - return true; - } - - return false; -} - /// Determines if the given type is safe for constant capture in C++. static bool isSafeForCXXConstantCapture(QualType type) { const RecordType *recordType = @@ -222,7 +205,7 @@ static bool isSafeForCXXConstantCapture(QualType type) { // Otherwise, we just have to make sure there aren't any mutable // fields that might have changed since initialization. - return !hasMutableField(record); + return !record->hasMutableFields(); } /// It is illegal to modify a const object after initialization. diff --git a/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp index d99230b556e..ea2b2d16d61 100644 --- a/clang/lib/CodeGen/CodeGenModule.cpp +++ b/clang/lib/CodeGen/CodeGenModule.cpp @@ -946,7 +946,9 @@ static bool DeclIsConstantGlobal(ASTContext &Context, const VarDecl *D, if (Context.getLangOptions().CPlusPlus) { if (const RecordType *Record = Context.getBaseElementType(D->getType())->getAs<RecordType>()) - return ConstantInit && cast<CXXRecordDecl>(Record->getDecl())->isPOD(); + return ConstantInit && + cast<CXXRecordDecl>(Record->getDecl())->isPOD() && + !cast<CXXRecordDecl>(Record->getDecl())->hasMutableFields(); } return true; diff --git a/clang/lib/Serialization/ASTReaderDecl.cpp b/clang/lib/Serialization/ASTReaderDecl.cpp index 85c8f079c00..feafe6f89e1 100644 --- a/clang/lib/Serialization/ASTReaderDecl.cpp +++ b/clang/lib/Serialization/ASTReaderDecl.cpp @@ -860,6 +860,7 @@ void ASTDeclReader::ReadCXXDefinitionData( Data.HasPrivateFields = Record[Idx++]; Data.HasProtectedFields = Record[Idx++]; Data.HasPublicFields = Record[Idx++]; + Data.HasMutableFields = Record[Idx++]; Data.HasTrivialDefaultConstructor = Record[Idx++]; Data.HasConstExprNonCopyMoveConstructor = Record[Idx++]; Data.HasTrivialCopyConstructor = Record[Idx++]; diff --git a/clang/lib/Serialization/ASTWriter.cpp b/clang/lib/Serialization/ASTWriter.cpp index aae62a8ff86..9682dfda121 100644 --- a/clang/lib/Serialization/ASTWriter.cpp +++ b/clang/lib/Serialization/ASTWriter.cpp @@ -3818,6 +3818,7 @@ void ASTWriter::AddCXXDefinitionData(const CXXRecordDecl *D, RecordDataImpl &Rec Record.push_back(Data.HasPrivateFields); Record.push_back(Data.HasProtectedFields); Record.push_back(Data.HasPublicFields); + Record.push_back(Data.HasMutableFields); Record.push_back(Data.HasTrivialDefaultConstructor); Record.push_back(Data.HasConstExprNonCopyMoveConstructor); Record.push_back(Data.HasTrivialCopyConstructor); |