diff options
Diffstat (limited to 'lib/AST/DeclCXX.cpp')
-rw-r--r-- | lib/AST/DeclCXX.cpp | 109 |
1 files changed, 74 insertions, 35 deletions
diff --git a/lib/AST/DeclCXX.cpp b/lib/AST/DeclCXX.cpp index 2a1fac8509..de06ecb4ca 100644 --- a/lib/AST/DeclCXX.cpp +++ b/lib/AST/DeclCXX.cpp @@ -448,6 +448,15 @@ void CXXRecordDecl::addedMember(Decl *D) { FunctionTemplateDecl *FunTmpl = dyn_cast<FunctionTemplateDecl>(D); if (FunTmpl) D = FunTmpl->getTemplatedDecl(); + + // FIXME: Pass NamedDecl* to addedMember? + Decl *DUnderlying = D; + if (auto *ND = dyn_cast<NamedDecl>(DUnderlying)) { + DUnderlying = ND->getUnderlyingDecl(); + if (FunctionTemplateDecl *UnderlyingFunTmpl = + dyn_cast<FunctionTemplateDecl>(DUnderlying)) + DUnderlying = UnderlyingFunTmpl->getTemplatedDecl(); + } if (CXXMethodDecl *Method = dyn_cast<CXXMethodDecl>(D)) { if (Method->isVirtual()) { @@ -503,15 +512,10 @@ void CXXRecordDecl::addedMember(Decl *D) { data().PlainOldData = false; } - // Technically, "user-provided" is only defined for special member - // functions, but the intent of the standard is clearly that it should apply - // to all functions. - bool UserProvided = Constructor->isUserProvided(); - if (Constructor->isDefaultConstructor()) { SMKind |= SMF_DefaultConstructor; - if (UserProvided) + if (Constructor->isUserProvided()) data().UserProvidedDefaultConstructor = true; if (Constructor->isConstexpr()) data().HasConstexprDefaultConstructor = true; @@ -529,9 +533,17 @@ void CXXRecordDecl::addedMember(Decl *D) { } else if (Constructor->isMoveConstructor()) SMKind |= SMF_MoveConstructor; } + } + // Handle constructors, including those inherited from base classes. + if (CXXConstructorDecl *Constructor = + dyn_cast<CXXConstructorDecl>(DUnderlying)) { // Record if we see any constexpr constructors which are neither copy // nor move constructors. + // C++1z [basic.types]p10: + // [...] has at least one constexpr constructor or constructor template + // (possibly inherited from a base class) that is not a copy or move + // constructor [...] if (Constructor->isConstexpr() && !Constructor->isCopyOrMoveConstructor()) data().HasConstexprNonCopyMoveConstructor = true; @@ -541,8 +553,12 @@ void CXXRecordDecl::addedMember(Decl *D) { // C++11 [dcl.init.aggr]p1: // An aggregate is an array or a class with no user-provided // constructors [...]. + // C++11 [dcl.init.aggr]p1: + // An aggregate is an array or a class with no user-provided + // constructors (including those inherited from a base class) [...]. if (getASTContext().getLangOpts().CPlusPlus11 - ? UserProvided : !Constructor->isImplicit()) + ? Constructor->isUserProvided() + : !Constructor->isImplicit()) data().Aggregate = false; } @@ -1784,11 +1800,15 @@ SourceRange CXXCtorInitializer::getSourceRange() const { void CXXConstructorDecl::anchor() { } -CXXConstructorDecl * -CXXConstructorDecl::CreateDeserialized(ASTContext &C, unsigned ID) { - return new (C, ID) CXXConstructorDecl(C, nullptr, SourceLocation(), - DeclarationNameInfo(), QualType(), - nullptr, false, false, false, false); +CXXConstructorDecl *CXXConstructorDecl::CreateDeserialized(ASTContext &C, + unsigned ID, + bool Inherited) { + unsigned Extra = additionalSizeToAlloc<InheritedConstructor>(Inherited); + auto *Result = new (C, ID, Extra) CXXConstructorDecl( + C, nullptr, SourceLocation(), DeclarationNameInfo(), QualType(), nullptr, + false, false, false, false, InheritedConstructor()); + Result->IsInheritingConstructor = Inherited; + return Result; } CXXConstructorDecl * @@ -1797,13 +1817,16 @@ CXXConstructorDecl::Create(ASTContext &C, CXXRecordDecl *RD, const DeclarationNameInfo &NameInfo, QualType T, TypeSourceInfo *TInfo, bool isExplicit, bool isInline, - bool isImplicitlyDeclared, bool isConstexpr) { + bool isImplicitlyDeclared, bool isConstexpr, + InheritedConstructor Inherited) { assert(NameInfo.getName().getNameKind() == DeclarationName::CXXConstructorName && "Name must refer to a constructor"); - return new (C, RD) CXXConstructorDecl(C, RD, StartLoc, NameInfo, T, TInfo, - isExplicit, isInline, - isImplicitlyDeclared, isConstexpr); + unsigned Extra = + additionalSizeToAlloc<InheritedConstructor>(Inherited ? 1 : 0); + return new (C, RD, Extra) CXXConstructorDecl( + C, RD, StartLoc, NameInfo, T, TInfo, isExplicit, isInline, + isImplicitlyDeclared, isConstexpr, Inherited); } CXXConstructorDecl::init_const_iterator CXXConstructorDecl::init_begin() const { @@ -1918,23 +1941,6 @@ bool CXXConstructorDecl::isSpecializationCopyingObject() const { return true; } -const CXXConstructorDecl *CXXConstructorDecl::getInheritedConstructor() const { - // Hack: we store the inherited constructor in the overridden method table - method_iterator It = getASTContext().overridden_methods_begin(this); - if (It == getASTContext().overridden_methods_end(this)) - return nullptr; - - return cast<CXXConstructorDecl>(*It); -} - -void -CXXConstructorDecl::setInheritedConstructor(const CXXConstructorDecl *BaseCtor){ - // Hack: we store the inherited constructor in the overridden method table - assert(getASTContext().overridden_methods_size(this) == 0 && - "Base ctor already set."); - getASTContext().addOverriddenMethod(this, BaseCtor); -} - void CXXDestructorDecl::anchor() { } CXXDestructorDecl * @@ -2130,10 +2136,24 @@ NamespaceAliasDecl::CreateDeserialized(ASTContext &C, unsigned ID) { void UsingShadowDecl::anchor() { } +UsingShadowDecl::UsingShadowDecl(Kind K, ASTContext &C, DeclContext *DC, + SourceLocation Loc, UsingDecl *Using, + NamedDecl *Target) + : NamedDecl(K, DC, Loc, Using ? Using->getDeclName() : DeclarationName()), + redeclarable_base(C), Underlying(Target), + UsingOrNextShadow(cast<NamedDecl>(Using)) { + if (Target) + IdentifierNamespace = Target->getIdentifierNamespace(); + setImplicit(); +} + +UsingShadowDecl::UsingShadowDecl(Kind K, ASTContext &C, EmptyShell Empty) + : NamedDecl(K, nullptr, SourceLocation(), DeclarationName()), + redeclarable_base(C), Underlying(), UsingOrNextShadow() {} + UsingShadowDecl * UsingShadowDecl::CreateDeserialized(ASTContext &C, unsigned ID) { - return new (C, ID) UsingShadowDecl(C, nullptr, SourceLocation(), - nullptr, nullptr); + return new (C, ID) UsingShadowDecl(UsingShadow, C, EmptyShell()); } UsingDecl *UsingShadowDecl::getUsingDecl() const { @@ -2144,6 +2164,25 @@ UsingDecl *UsingShadowDecl::getUsingDecl() const { return cast<UsingDecl>(Shadow->UsingOrNextShadow); } +void ConstructorUsingShadowDecl::anchor() { } + +ConstructorUsingShadowDecl * +ConstructorUsingShadowDecl::Create(ASTContext &C, DeclContext *DC, + SourceLocation Loc, UsingDecl *Using, + NamedDecl *Target, bool IsVirtual) { + return new (C, DC) ConstructorUsingShadowDecl(C, DC, Loc, Using, Target, + IsVirtual); +} + +ConstructorUsingShadowDecl * +ConstructorUsingShadowDecl::CreateDeserialized(ASTContext &C, unsigned ID) { + return new (C, ID) ConstructorUsingShadowDecl(C, EmptyShell()); +} + +CXXRecordDecl *ConstructorUsingShadowDecl::getNominatedBaseClass() const { + return getUsingDecl()->getQualifier()->getAsRecordDecl(); +} + void UsingDecl::anchor() { } void UsingDecl::addShadowDecl(UsingShadowDecl *S) { |