diff options
Diffstat (limited to 'lib/AST/DeclCXX.cpp')
-rw-r--r-- | lib/AST/DeclCXX.cpp | 84 |
1 files changed, 64 insertions, 20 deletions
diff --git a/lib/AST/DeclCXX.cpp b/lib/AST/DeclCXX.cpp index a9db65a515184..2e5cec9c108f1 100644 --- a/lib/AST/DeclCXX.cpp +++ b/lib/AST/DeclCXX.cpp @@ -18,6 +18,7 @@ #include "clang/AST/DeclTemplate.h" #include "clang/AST/Expr.h" #include "clang/AST/ExprCXX.h" +#include "clang/AST/ODRHash.h" #include "clang/AST/TypeLoc.h" #include "clang/Basic/IdentifierTable.h" #include "llvm/ADT/STLExtras.h" @@ -67,12 +68,14 @@ CXXRecordDecl::DefinitionData::DefinitionData(CXXRecordDecl *D) HasConstexprDefaultConstructor(false), HasNonLiteralTypeFieldsOrBases(false), ComputedVisibleConversions(false), UserProvidedDefaultConstructor(false), DeclaredSpecialMembers(0), - ImplicitCopyConstructorHasConstParam(true), + ImplicitCopyConstructorCanHaveConstParamForVBase(true), + ImplicitCopyConstructorCanHaveConstParamForNonVBase(true), ImplicitCopyAssignmentHasConstParam(true), HasDeclaredCopyConstructorWithConstParam(false), HasDeclaredCopyAssignmentWithConstParam(false), IsLambda(false), - IsParsingBaseSpecifiers(false), NumBases(0), NumVBases(0), Bases(), - VBases(), Definition(D), FirstFriend() {} + IsParsingBaseSpecifiers(false), HasODRHash(false), ODRHash(0), + NumBases(0), NumVBases(0), Bases(), VBases(), Definition(D), + FirstFriend() {} CXXBaseSpecifier *CXXRecordDecl::DefinitionData::getBasesSlowCase() const { return Bases.get(Definition->getASTContext().getExternalSource()); @@ -226,7 +229,7 @@ CXXRecordDecl::setBases(CXXBaseSpecifier const * const *Bases, // 'const B&' or 'const volatile B&' [...] if (CXXRecordDecl *VBaseDecl = VBase.getType()->getAsCXXRecordDecl()) if (!VBaseDecl->hasCopyConstructorWithConstParam()) - data().ImplicitCopyConstructorHasConstParam = false; + data().ImplicitCopyConstructorCanHaveConstParamForVBase = false; // C++1z [dcl.init.agg]p1: // An aggregate is a class with [...] no virtual base classes @@ -263,6 +266,14 @@ CXXRecordDecl::setBases(CXXBaseSpecifier const * const *Bases, // In the definition of a constexpr constructor [...] // -- the class shall not have any virtual base classes data().DefaultedDefaultConstructorIsConstexpr = false; + + // C++1z [class.copy]p8: + // The implicitly-declared copy constructor for a class X will have + // the form 'X::X(const X&)' if each potentially constructed subobject + // has a copy constructor whose first parameter is of type + // 'const B&' or 'const volatile B&' [...] + if (!BaseClassDecl->hasCopyConstructorWithConstParam()) + data().ImplicitCopyConstructorCanHaveConstParamForVBase = false; } else { // C++ [class.ctor]p5: // A default constructor is trivial [...] if: @@ -305,6 +316,14 @@ CXXRecordDecl::setBases(CXXBaseSpecifier const * const *Bases, // default constructor is constexpr. if (!BaseClassDecl->hasConstexprDefaultConstructor()) data().DefaultedDefaultConstructorIsConstexpr = false; + + // C++1z [class.copy]p8: + // The implicitly-declared copy constructor for a class X will have + // the form 'X::X(const X&)' if each potentially constructed subobject + // has a copy constructor whose first parameter is of type + // 'const B&' or 'const volatile B&' [...] + if (!BaseClassDecl->hasCopyConstructorWithConstParam()) + data().ImplicitCopyConstructorCanHaveConstParamForNonVBase = false; } // C++ [class.ctor]p3: @@ -324,14 +343,6 @@ CXXRecordDecl::setBases(CXXBaseSpecifier const * const *Bases, if (!BaseClassDecl->hasCopyAssignmentWithConstParam()) data().ImplicitCopyAssignmentHasConstParam = false; - // C++11 [class.copy]p8: - // The implicitly-declared copy constructor for a class X will have - // the form 'X::X(const X&)' if each direct [...] base class B of X - // has a copy constructor whose first parameter is of type - // 'const B&' or 'const volatile B&' [...] - if (!BaseClassDecl->hasCopyConstructorWithConstParam()) - data().ImplicitCopyConstructorHasConstParam = false; - // A class has an Objective-C object member if... or any of its bases // has an Objective-C object member. if (BaseClassDecl->hasObjectMember()) @@ -371,6 +382,23 @@ CXXRecordDecl::setBases(CXXBaseSpecifier const * const *Bases, data().IsParsingBaseSpecifiers = false; } +unsigned CXXRecordDecl::getODRHash() const { + assert(hasDefinition() && "ODRHash only for records with definitions"); + + // Previously calculated hash is stored in DefinitionData. + if (DefinitionData->HasODRHash) + return DefinitionData->ODRHash; + + // Only calculate hash on first call of getODRHash per record. + ODRHash Hash; + Hash.AddCXXRecordDecl(getDefinition()); + DefinitionData->HasODRHash = true; + DefinitionData->ODRHash = Hash.CalculateHash(); + + return DefinitionData->ODRHash; +} + + void CXXRecordDecl::addedClassSubobject(CXXRecordDecl *Subobj) { // C++11 [class.copy]p11: // A defaulted copy/move constructor for a class X is defined as @@ -702,9 +730,7 @@ void CXXRecordDecl::addedMember(Decl *D) { ASTContext &Context = getASTContext(); QualType T = Context.getBaseElementType(Field->getType()); if (T->isObjCRetainableType() || T.isObjCGCStrong()) { - if (!Context.getLangOpts().ObjCAutoRefCount) { - setHasObjectMember(true); - } else if (T.getObjCLifetime() != Qualifiers::OCL_ExplicitNone) { + if (T.hasNonTrivialObjCLifetime()) { // Objective-C Automatic Reference Counting: // If a class has a non-static data member of Objective-C pointer // type (or array thereof), it is a non-POD type and its @@ -716,6 +742,8 @@ void CXXRecordDecl::addedMember(Decl *D) { Data.PlainOldData = false; Data.HasTrivialSpecialMembers = 0; Data.HasIrrelevantDestructor = false; + } else if (!Context.getLangOpts().ObjCAutoRefCount) { + setHasObjectMember(true); } } else if (!T.isCXX98PODType(Context)) data().PlainOldData = false; @@ -905,12 +933,11 @@ void CXXRecordDecl::addedMember(Decl *D) { // C++11 [class.copy]p8: // The implicitly-declared copy constructor for a class X will have - // the form 'X::X(const X&)' if [...] for all the non-static data - // members of X that are of a class type M (or array thereof), each - // such class type has a copy constructor whose first parameter is - // of type 'const M&' or 'const volatile M&'. + // the form 'X::X(const X&)' if each potentially constructed subobject + // of a class type M (or array thereof) has a copy constructor whose + // first parameter is of type 'const M&' or 'const volatile M&'. if (!FieldRec->hasCopyConstructorWithConstParam()) - data().ImplicitCopyConstructorHasConstParam = false; + data().ImplicitCopyConstructorCanHaveConstParamForNonVBase = false; // C++11 [class.copy]p18: // The implicitly-declared copy assignment oeprator for a class X will @@ -1472,6 +1499,23 @@ bool CXXRecordDecl::mayBeAbstract() const { return false; } +void CXXDeductionGuideDecl::anchor() { } + +CXXDeductionGuideDecl *CXXDeductionGuideDecl::Create( + ASTContext &C, DeclContext *DC, SourceLocation StartLoc, bool IsExplicit, + const DeclarationNameInfo &NameInfo, QualType T, TypeSourceInfo *TInfo, + SourceLocation EndLocation) { + return new (C, DC) CXXDeductionGuideDecl(C, DC, StartLoc, IsExplicit, + NameInfo, T, TInfo, EndLocation); +} + +CXXDeductionGuideDecl *CXXDeductionGuideDecl::CreateDeserialized(ASTContext &C, + unsigned ID) { + return new (C, ID) CXXDeductionGuideDecl(C, nullptr, SourceLocation(), false, + DeclarationNameInfo(), QualType(), + nullptr, SourceLocation()); +} + void CXXMethodDecl::anchor() { } bool CXXMethodDecl::isStatic() const { |