diff options
Diffstat (limited to 'lib/AST/DeclCXX.cpp')
-rw-r--r-- | lib/AST/DeclCXX.cpp | 198 |
1 files changed, 139 insertions, 59 deletions
diff --git a/lib/AST/DeclCXX.cpp b/lib/AST/DeclCXX.cpp index 81f94148d6ed..a9db65a51518 100644 --- a/lib/AST/DeclCXX.cpp +++ b/lib/AST/DeclCXX.cpp @@ -533,6 +533,12 @@ void CXXRecordDecl::addedMember(Decl *D) { } else if (Constructor->isMoveConstructor()) SMKind |= SMF_MoveConstructor; } + + // C++11 [dcl.init.aggr]p1: DR1518 + // An aggregate is an array or a class with no user-provided, explicit, or + // inherited constructors + if (Constructor->isUserProvided() || Constructor->isExplicit()) + data().Aggregate = false; } // Handle constructors, including those inherited from base classes. @@ -546,20 +552,6 @@ void CXXRecordDecl::addedMember(Decl *D) { // constructor [...] if (Constructor->isConstexpr() && !Constructor->isCopyOrMoveConstructor()) data().HasConstexprNonCopyMoveConstructor = true; - - // C++ [dcl.init.aggr]p1: - // An aggregate is an array or a class with no user-declared - // constructors [...]. - // 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 - ? Constructor->isUserProvided() - : !Constructor->isImplicit()) - data().Aggregate = false; } // Handle destructors. @@ -739,7 +731,7 @@ void CXXRecordDecl::addedMember(Decl *D) { } if (!Field->hasInClassInitializer() && !Field->isMutable()) { - if (CXXRecordDecl *FieldType = Field->getType()->getAsCXXRecordDecl()) { + if (CXXRecordDecl *FieldType = T->getAsCXXRecordDecl()) { if (FieldType->hasDefinition() && !FieldType->allowConstDefaultInit()) data().HasUninitializedFields = true; } else { @@ -989,8 +981,12 @@ void CXXRecordDecl::addedMember(Decl *D) { if (UsingDecl *Using = dyn_cast<UsingDecl>(D)) { if (Using->getDeclName().getNameKind() == - DeclarationName::CXXConstructorName) + DeclarationName::CXXConstructorName) { data().HasInheritedConstructor = true; + // C++1z [dcl.init.aggr]p1: + // An aggregate is [...] a class [...] with no inherited constructors + data().Aggregate = false; + } if (Using->getDeclName().getCXXOverloadedOperator() == OO_Equal) data().HasInheritedAssignment = true; @@ -1107,6 +1103,12 @@ CXXRecordDecl::getGenericLambdaTemplateParameterList() const { return nullptr; } +Decl *CXXRecordDecl::getLambdaContextDecl() const { + assert(isLambda() && "Not a lambda closure type!"); + ExternalASTSource *Source = getParentASTContext().getExternalSource(); + return getLambdaData().ContextDecl.get(Source); +} + static CanQualType GetConversionType(ASTContext &Context, NamedDecl *Conv) { QualType T = cast<CXXConversionDecl>(Conv->getUnderlyingDecl()->getAsFunction()) @@ -1571,17 +1573,35 @@ bool CXXMethodDecl::isUsualDeallocationFunction() const { // deallocation function. [...] if (getNumParams() == 1) return true; - - // C++ [basic.stc.dynamic.deallocation]p2: + unsigned UsualParams = 1; + + // C++ <=14 [basic.stc.dynamic.deallocation]p2: // [...] If class T does not declare such an operator delete but does // declare a member deallocation function named operator delete with // exactly two parameters, the second of which has type std::size_t (18.1), // then this function is a usual deallocation function. + // + // C++17 says a usual deallocation function is one with the signature + // (void* [, size_t] [, std::align_val_t] [, ...]) + // and all such functions are usual deallocation functions. It's not clear + // that allowing varargs functions was intentional. ASTContext &Context = getASTContext(); - if (getNumParams() != 2 || - !Context.hasSameUnqualifiedType(getParamDecl(1)->getType(), - Context.getSizeType())) + if (UsualParams < getNumParams() && + Context.hasSameUnqualifiedType(getParamDecl(UsualParams)->getType(), + Context.getSizeType())) + ++UsualParams; + + if (UsualParams < getNumParams() && + getParamDecl(UsualParams)->getType()->isAlignValT()) + ++UsualParams; + + if (UsualParams != getNumParams()) return false; + + // In C++17 onwards, all potential usual deallocation functions are actual + // usual deallocation functions. + if (Context.getLangOpts().AlignedAllocation) + return true; // This function is a usual deallocation function if there are no // single-parameter deallocation functions of the same kind. @@ -1714,7 +1734,7 @@ CXXCtorInitializer::CXXCtorInitializer(ASTContext &Context, SourceLocation EllipsisLoc) : Initializee(TInfo), MemberOrEllipsisLocation(EllipsisLoc), Init(Init), LParenLoc(L), RParenLoc(R), IsDelegating(false), IsVirtual(IsVirtual), - IsWritten(false), SourceOrderOrNumArrayIndices(0) + IsWritten(false), SourceOrder(0) { } @@ -1725,7 +1745,7 @@ CXXCtorInitializer::CXXCtorInitializer(ASTContext &Context, SourceLocation R) : Initializee(Member), MemberOrEllipsisLocation(MemberLoc), Init(Init), LParenLoc(L), RParenLoc(R), IsDelegating(false), IsVirtual(false), - IsWritten(false), SourceOrderOrNumArrayIndices(0) + IsWritten(false), SourceOrder(0) { } @@ -1736,7 +1756,7 @@ CXXCtorInitializer::CXXCtorInitializer(ASTContext &Context, SourceLocation R) : Initializee(Member), MemberOrEllipsisLocation(MemberLoc), Init(Init), LParenLoc(L), RParenLoc(R), IsDelegating(false), IsVirtual(false), - IsWritten(false), SourceOrderOrNumArrayIndices(0) + IsWritten(false), SourceOrder(0) { } @@ -1746,38 +1766,10 @@ CXXCtorInitializer::CXXCtorInitializer(ASTContext &Context, SourceLocation R) : Initializee(TInfo), MemberOrEllipsisLocation(), Init(Init), LParenLoc(L), RParenLoc(R), IsDelegating(true), IsVirtual(false), - IsWritten(false), SourceOrderOrNumArrayIndices(0) + IsWritten(false), SourceOrder(0) { } -CXXCtorInitializer::CXXCtorInitializer(ASTContext &Context, - FieldDecl *Member, - SourceLocation MemberLoc, - SourceLocation L, Expr *Init, - SourceLocation R, - VarDecl **Indices, - unsigned NumIndices) - : Initializee(Member), MemberOrEllipsisLocation(MemberLoc), Init(Init), - LParenLoc(L), RParenLoc(R), IsDelegating(false), IsVirtual(false), - IsWritten(false), SourceOrderOrNumArrayIndices(NumIndices) -{ - std::uninitialized_copy(Indices, Indices + NumIndices, - getTrailingObjects<VarDecl *>()); -} - -CXXCtorInitializer *CXXCtorInitializer::Create(ASTContext &Context, - FieldDecl *Member, - SourceLocation MemberLoc, - SourceLocation L, Expr *Init, - SourceLocation R, - VarDecl **Indices, - unsigned NumIndices) { - void *Mem = Context.Allocate(totalSizeToAlloc<VarDecl *>(NumIndices), - llvm::alignOf<CXXCtorInitializer>()); - return new (Mem) CXXCtorInitializer(Context, Member, MemberLoc, L, Init, R, - Indices, NumIndices); -} - TypeLoc CXXCtorInitializer::getBaseClassLoc() const { if (isBaseInitializer()) return Initializee.get<TypeSourceInfo*>()->getTypeLoc(); @@ -2253,15 +2245,37 @@ SourceRange UsingDecl::getSourceRange() const { return SourceRange(Begin, getNameInfo().getEndLoc()); } +void UsingPackDecl::anchor() { } + +UsingPackDecl *UsingPackDecl::Create(ASTContext &C, DeclContext *DC, + NamedDecl *InstantiatedFrom, + ArrayRef<NamedDecl *> UsingDecls) { + size_t Extra = additionalSizeToAlloc<NamedDecl *>(UsingDecls.size()); + return new (C, DC, Extra) UsingPackDecl(DC, InstantiatedFrom, UsingDecls); +} + +UsingPackDecl *UsingPackDecl::CreateDeserialized(ASTContext &C, unsigned ID, + unsigned NumExpansions) { + size_t Extra = additionalSizeToAlloc<NamedDecl *>(NumExpansions); + auto *Result = new (C, ID, Extra) UsingPackDecl(nullptr, nullptr, None); + Result->NumExpansions = NumExpansions; + auto *Trail = Result->getTrailingObjects<NamedDecl *>(); + for (unsigned I = 0; I != NumExpansions; ++I) + new (Trail + I) NamedDecl*(nullptr); + return Result; +} + void UnresolvedUsingValueDecl::anchor() { } UnresolvedUsingValueDecl * UnresolvedUsingValueDecl::Create(ASTContext &C, DeclContext *DC, SourceLocation UsingLoc, NestedNameSpecifierLoc QualifierLoc, - const DeclarationNameInfo &NameInfo) { + const DeclarationNameInfo &NameInfo, + SourceLocation EllipsisLoc) { return new (C, DC) UnresolvedUsingValueDecl(DC, C.DependentTy, UsingLoc, - QualifierLoc, NameInfo); + QualifierLoc, NameInfo, + EllipsisLoc); } UnresolvedUsingValueDecl * @@ -2269,7 +2283,8 @@ UnresolvedUsingValueDecl::CreateDeserialized(ASTContext &C, unsigned ID) { return new (C, ID) UnresolvedUsingValueDecl(nullptr, QualType(), SourceLocation(), NestedNameSpecifierLoc(), - DeclarationNameInfo()); + DeclarationNameInfo(), + SourceLocation()); } SourceRange UnresolvedUsingValueDecl::getSourceRange() const { @@ -2286,17 +2301,18 @@ UnresolvedUsingTypenameDecl::Create(ASTContext &C, DeclContext *DC, SourceLocation TypenameLoc, NestedNameSpecifierLoc QualifierLoc, SourceLocation TargetNameLoc, - DeclarationName TargetName) { + DeclarationName TargetName, + SourceLocation EllipsisLoc) { return new (C, DC) UnresolvedUsingTypenameDecl( DC, UsingLoc, TypenameLoc, QualifierLoc, TargetNameLoc, - TargetName.getAsIdentifierInfo()); + TargetName.getAsIdentifierInfo(), EllipsisLoc); } UnresolvedUsingTypenameDecl * UnresolvedUsingTypenameDecl::CreateDeserialized(ASTContext &C, unsigned ID) { return new (C, ID) UnresolvedUsingTypenameDecl( nullptr, SourceLocation(), SourceLocation(), NestedNameSpecifierLoc(), - SourceLocation(), nullptr); + SourceLocation(), nullptr, SourceLocation()); } void StaticAssertDecl::anchor() { } @@ -2317,6 +2333,70 @@ StaticAssertDecl *StaticAssertDecl::CreateDeserialized(ASTContext &C, nullptr, SourceLocation(), false); } +void BindingDecl::anchor() {} + +BindingDecl *BindingDecl::Create(ASTContext &C, DeclContext *DC, + SourceLocation IdLoc, IdentifierInfo *Id) { + return new (C, DC) BindingDecl(DC, IdLoc, Id); +} + +BindingDecl *BindingDecl::CreateDeserialized(ASTContext &C, unsigned ID) { + return new (C, ID) BindingDecl(nullptr, SourceLocation(), nullptr); +} + +VarDecl *BindingDecl::getHoldingVar() const { + Expr *B = getBinding(); + if (!B) + return nullptr; + auto *DRE = dyn_cast<DeclRefExpr>(B->IgnoreImplicit()); + if (!DRE) + return nullptr; + + auto *VD = dyn_cast<VarDecl>(DRE->getDecl()); + assert(VD->isImplicit() && "holding var for binding decl not implicit"); + return VD; +} + +void DecompositionDecl::anchor() {} + +DecompositionDecl *DecompositionDecl::Create(ASTContext &C, DeclContext *DC, + SourceLocation StartLoc, + SourceLocation LSquareLoc, + QualType T, TypeSourceInfo *TInfo, + StorageClass SC, + ArrayRef<BindingDecl *> Bindings) { + size_t Extra = additionalSizeToAlloc<BindingDecl *>(Bindings.size()); + return new (C, DC, Extra) + DecompositionDecl(C, DC, StartLoc, LSquareLoc, T, TInfo, SC, Bindings); +} + +DecompositionDecl *DecompositionDecl::CreateDeserialized(ASTContext &C, + unsigned ID, + unsigned NumBindings) { + size_t Extra = additionalSizeToAlloc<BindingDecl *>(NumBindings); + auto *Result = new (C, ID, Extra) + DecompositionDecl(C, nullptr, SourceLocation(), SourceLocation(), + QualType(), nullptr, StorageClass(), None); + // Set up and clean out the bindings array. + Result->NumBindings = NumBindings; + auto *Trail = Result->getTrailingObjects<BindingDecl *>(); + for (unsigned I = 0; I != NumBindings; ++I) + new (Trail + I) BindingDecl*(nullptr); + return Result; +} + +void DecompositionDecl::printName(llvm::raw_ostream &os) const { + os << '['; + bool Comma = false; + for (auto *B : bindings()) { + if (Comma) + os << ", "; + B->printName(os); + Comma = true; + } + os << ']'; +} + MSPropertyDecl *MSPropertyDecl::Create(ASTContext &C, DeclContext *DC, SourceLocation L, DeclarationName N, QualType T, TypeSourceInfo *TInfo, |