diff options
Diffstat (limited to 'clang/lib')
-rw-r--r-- | clang/lib/AST/DeclCXX.cpp | 86 | ||||
-rw-r--r-- | clang/lib/Sema/SemaDecl.cpp | 22 | ||||
-rw-r--r-- | clang/lib/Sema/SemaDeclCXX.cpp | 51 | ||||
-rw-r--r-- | clang/lib/Sema/SemaTemplateInstantiate.cpp | 7 | ||||
-rw-r--r-- | clang/lib/Sema/SemaTemplateInstantiateDecl.cpp | 3 |
5 files changed, 80 insertions, 89 deletions
diff --git a/clang/lib/AST/DeclCXX.cpp b/clang/lib/AST/DeclCXX.cpp index 0e37bc7801c..7cdffb7b44e 100644 --- a/clang/lib/AST/DeclCXX.cpp +++ b/clang/lib/AST/DeclCXX.cpp @@ -110,6 +110,12 @@ CXXRecordDecl::setBases(CXXBaseSpecifier const * const *Bases, if (!BaseClassDecl->isEmpty()) data().Empty = false; + // C++ [class.virtual]p1: + // A class that declares or inherits a virtual function is called a + // polymorphic class. + if (BaseClassDecl->isPolymorphic()) + data().Polymorphic = true; + // Now go through all virtual bases of this base and add them. for (CXXRecordDecl::base_class_iterator VBase = BaseClassDecl->vbases_begin(), @@ -128,7 +134,45 @@ CXXRecordDecl::setBases(CXXBaseSpecifier const * const *Bases, // T is a class type, but not a union type, with ... no virtual base // classes data().Empty = false; + + // C++ [class.ctor]p5: + // A constructor is trivial if its class has no virtual base classes. + data().HasTrivialConstructor = false; + + // C++ [class.copy]p6: + // A copy constructor is trivial if its class has no virtual base + // classes. + data().HasTrivialCopyConstructor = false; + + // C++ [class.copy]p11: + // A copy assignment operator is trivial if its class has no virtual + // base classes. + data().HasTrivialCopyAssignment = false; + } else { + // C++ [class.ctor]p5: + // A constructor is trivial if all the direct base classes of its + // class have trivial constructors. + if (!BaseClassDecl->hasTrivialConstructor()) + data().HasTrivialConstructor = false; + + // C++ [class.copy]p6: + // A copy constructor is trivial if all the direct base classes of its + // class have trivial copy constructors. + if (!BaseClassDecl->hasTrivialCopyConstructor()) + data().HasTrivialCopyConstructor = false; + + // C++ [class.copy]p11: + // A copy assignment operator is trivial if all the direct base classes + // of its class have trivial copy assignment operators. + if (!BaseClassDecl->hasTrivialCopyAssignment()) + data().HasTrivialCopyAssignment = false; } + + // C++ [class.ctor]p3: + // A destructor is trivial if all the direct base classes of its class + // have trivial destructors. + if (!BaseClassDecl->hasTrivialDestructor()) + data().HasTrivialDestructor = false; } if (VBases.empty()) @@ -298,6 +342,17 @@ CXXRecordDecl::addedMember(Decl *D) { // Virtual functions make the class non-empty. // FIXME: Standard ref? data().Empty = false; + + // C++ [class.virtual]p1: + // A class that declares or inherits a virtual function is called a + // polymorphic class. + data().Polymorphic = true; + + // None of the special member functions are trivial. + data().HasTrivialConstructor = false; + data().HasTrivialCopyConstructor = false; + data().HasTrivialCopyAssignment = false; + // FIXME: Destructor? } } @@ -379,6 +434,13 @@ CXXRecordDecl::addedMember(Decl *D) { // destructor. data().PlainOldData = false; + // C++ [class.dtor]p3: + // A destructor is trivial if it is an implicitly-declared destructor and + // [...]. + // + // FIXME: C++0x: don't do this for "= default" destructors + data().HasTrivialDestructor = false; + return; } @@ -448,6 +510,22 @@ CXXRecordDecl::addedMember(Decl *D) { QualType T = Context.getBaseElementType(Field->getType()); if (!T->isPODType()) data().PlainOldData = false; + if (T->isReferenceType()) + data().HasTrivialConstructor = false; + + if (const RecordType *RecordTy = T->getAs<RecordType>()) { + CXXRecordDecl* FieldRec = cast<CXXRecordDecl>(RecordTy->getDecl()); + if (FieldRec->getDefinition()) { + if (!FieldRec->hasTrivialConstructor()) + data().HasTrivialConstructor = false; + if (!FieldRec->hasTrivialCopyConstructor()) + data().HasTrivialCopyConstructor = false; + if (!FieldRec->hasTrivialCopyAssignment()) + data().HasTrivialCopyAssignment = false; + if (!FieldRec->hasTrivialDestructor()) + data().HasTrivialDestructor = false; + } + } // If this is not a zero-length bit-field, then the class is not empty. if (data().Empty) { @@ -644,14 +722,6 @@ void CXXRecordDecl::removeConversion(const NamedDecl *ConvDecl) { llvm_unreachable("conversion not found in set!"); } -void CXXRecordDecl::setMethodAsVirtual(FunctionDecl *Method) { - Method->setVirtualAsWritten(true); - setPolymorphic(true); - setHasTrivialConstructor(false); - setHasTrivialCopyConstructor(false); - setHasTrivialCopyAssignment(false); -} - CXXRecordDecl *CXXRecordDecl::getInstantiatedFromMemberClass() const { if (MemberSpecializationInfo *MSInfo = getMemberSpecializationInfo()) return cast<CXXRecordDecl>(MSInfo->getInstantiatedFrom()); diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp index 544d9842c12..871cb9fd785 100644 --- a/clang/lib/Sema/SemaDecl.cpp +++ b/clang/lib/Sema/SemaDecl.cpp @@ -3444,8 +3444,7 @@ Sema::ActOnFunctionDeclarator(Scope* S, Declarator& D, DeclContext* DC, << FixItHint::CreateRemoval(D.getDeclSpec().getVirtualSpecLoc()); } else { // Okay: Add virtual to the method. - CXXRecordDecl *CurClass = cast<CXXRecordDecl>(DC); - CurClass->setMethodAsVirtual(NewFD); + NewFD->setVirtualAsWritten(true); } } @@ -3946,11 +3945,6 @@ void Sema::CheckFunctionDeclaration(Scope *S, FunctionDecl *NewFD, return NewFD->setInvalidDecl(); } } - - // C++ [class.dtor]p3: A destructor is trivial if it is an implicitly- - // declared destructor. - // FIXME: C++0x: don't do this for "= default" destructors - Record->setHasTrivialDestructor(false); } else if (CXXConversionDecl *Conversion = dyn_cast<CXXConversionDecl>(NewFD)) { ActOnConversionDeclarator(Conversion); @@ -6204,23 +6198,9 @@ FieldDecl *Sema::CheckFieldDecl(DeclarationName Name, QualType T, } if (!InvalidDecl && getLangOptions().CPlusPlus) { - CXXRecordDecl* CXXRecord = cast<CXXRecordDecl>(Record); - - if (T->isReferenceType()) - CXXRecord->setHasTrivialConstructor(false); - if (const RecordType *RT = EltTy->getAs<RecordType>()) { CXXRecordDecl* RDecl = cast<CXXRecordDecl>(RT->getDecl()); if (RDecl->getDefinition()) { - if (!RDecl->hasTrivialConstructor()) - CXXRecord->setHasTrivialConstructor(false); - if (!RDecl->hasTrivialCopyConstructor()) - CXXRecord->setHasTrivialCopyConstructor(false); - if (!RDecl->hasTrivialCopyAssignment()) - CXXRecord->setHasTrivialCopyAssignment(false); - if (!RDecl->hasTrivialDestructor()) - CXXRecord->setHasTrivialDestructor(false); - // C++ 9.5p1: An object of a class with a non-trivial // constructor, a non-trivial copy constructor, a non-trivial // destructor, or a non-trivial copy assignment operator diff --git a/clang/lib/Sema/SemaDeclCXX.cpp b/clang/lib/Sema/SemaDeclCXX.cpp index c9a19dd6258..63acb095a66 100644 --- a/clang/lib/Sema/SemaDeclCXX.cpp +++ b/clang/lib/Sema/SemaDeclCXX.cpp @@ -502,8 +502,6 @@ Sema::CheckBaseSpecifier(CXXRecordDecl *Class, return 0; } - SetClassDeclAttributesFromBase(Class, CXXBaseDecl, Virtual); - if (BaseDecl->isInvalidDecl()) Class->setInvalidDecl(); @@ -513,55 +511,6 @@ Sema::CheckBaseSpecifier(CXXRecordDecl *Class, Access, TInfo); } -void Sema::SetClassDeclAttributesFromBase(CXXRecordDecl *Class, - const CXXRecordDecl *BaseClass, - bool BaseIsVirtual) { - // C++ [class.virtual]p1: - // A class that [...] inherits a virtual function is called a polymorphic - // class. - if (BaseClass->isPolymorphic()) - Class->setPolymorphic(true); - - if (BaseIsVirtual) { - // C++ [class.ctor]p5: - // A constructor is trivial if its class has no virtual base classes. - Class->setHasTrivialConstructor(false); - - // C++ [class.copy]p6: - // A copy constructor is trivial if its class has no virtual base classes. - Class->setHasTrivialCopyConstructor(false); - - // C++ [class.copy]p11: - // A copy assignment operator is trivial if its class has no virtual - // base classes. - Class->setHasTrivialCopyAssignment(false); - } else { - // C++ [class.ctor]p5: - // A constructor is trivial if all the direct base classes of its - // class have trivial constructors. - if (!BaseClass->hasTrivialConstructor()) - Class->setHasTrivialConstructor(false); - - // C++ [class.copy]p6: - // A copy constructor is trivial if all the direct base classes of its - // class have trivial copy constructors. - if (!BaseClass->hasTrivialCopyConstructor()) - Class->setHasTrivialCopyConstructor(false); - - // C++ [class.copy]p11: - // A copy assignment operator is trivial if all the direct base classes - // of its class have trivial copy assignment operators. - if (!BaseClass->hasTrivialCopyAssignment()) - Class->setHasTrivialCopyAssignment(false); - } - - // C++ [class.ctor]p3: - // A destructor is trivial if all the direct base classes of its class - // have trivial destructors. - if (!BaseClass->hasTrivialDestructor()) - Class->setHasTrivialDestructor(false); -} - /// ActOnBaseSpecifier - Parsed a base specifier. A base specifier is /// one entry in the base class list of a class specifier, for /// example: diff --git a/clang/lib/Sema/SemaTemplateInstantiate.cpp b/clang/lib/Sema/SemaTemplateInstantiate.cpp index 5520f640447..a2c3df653b7 100644 --- a/clang/lib/Sema/SemaTemplateInstantiate.cpp +++ b/clang/lib/Sema/SemaTemplateInstantiate.cpp @@ -1091,13 +1091,6 @@ Sema::SubstBaseSpecifiers(CXXRecordDecl *Instantiation, Base = Pattern->bases_begin(), BaseEnd = Pattern->bases_end(); Base != BaseEnd; ++Base) { if (!Base->getType()->isDependentType()) { - const CXXRecordDecl *BaseDecl = - cast<CXXRecordDecl>(Base->getType()->getAs<RecordType>()->getDecl()); - - // Make sure to set the attributes from the base. - SetClassDeclAttributesFromBase(Instantiation, BaseDecl, - Base->isVirtual()); - InstantiatedBases.push_back(new (Context) CXXBaseSpecifier(*Base)); continue; } diff --git a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp index f9ff20463ab..d87629151eb 100644 --- a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp +++ b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp @@ -1996,10 +1996,9 @@ TemplateDeclInstantiator::InitMethodInstantiation(CXXMethodDecl *New, if (InitFunctionInstantiation(New, Tmpl)) return true; - CXXRecordDecl *Record = cast<CXXRecordDecl>(Owner); New->setAccess(Tmpl->getAccess()); if (Tmpl->isVirtualAsWritten()) - Record->setMethodAsVirtual(New); + New->setVirtualAsWritten(true); // FIXME: attributes // FIXME: New needs a pointer to Tmpl |