diff options
Diffstat (limited to 'lib/AST/DeclCXX.cpp')
-rw-r--r-- | lib/AST/DeclCXX.cpp | 122 |
1 files changed, 98 insertions, 24 deletions
diff --git a/lib/AST/DeclCXX.cpp b/lib/AST/DeclCXX.cpp index 51e8e14f804a..31ffeb0dcd1e 100644 --- a/lib/AST/DeclCXX.cpp +++ b/lib/AST/DeclCXX.cpp @@ -128,7 +128,7 @@ CXXRecordDecl *CXXRecordDecl::Create(const ASTContext &C, TagKind TK, bool DelayTypeCreation) { auto *R = new (C, DC) CXXRecordDecl(CXXRecord, TK, C, DC, StartLoc, IdLoc, Id, PrevDecl); - R->MayHaveOutOfDateDef = C.getLangOpts().Modules; + R->setMayHaveOutOfDateDef(C.getLangOpts().Modules); // FIXME: DelayTypeCreation seems like such a hack if (!DelayTypeCreation) @@ -143,11 +143,11 @@ CXXRecordDecl::CreateLambda(const ASTContext &C, DeclContext *DC, LambdaCaptureDefault CaptureDefault) { auto *R = new (C, DC) CXXRecordDecl(CXXRecord, TTK_Class, C, DC, Loc, Loc, nullptr, nullptr); - R->IsBeingDefined = true; + R->setBeingDefined(true); R->DefinitionData = new (C) struct LambdaDefinitionData(R, Info, Dependent, IsGeneric, CaptureDefault); - R->MayHaveOutOfDateDef = false; + R->setMayHaveOutOfDateDef(false); R->setImplicit(true); C.getTypeDeclType(R, /*PrevDecl=*/nullptr); return R; @@ -158,7 +158,7 @@ CXXRecordDecl::CreateDeserialized(const ASTContext &C, unsigned ID) { auto *R = new (C, ID) CXXRecordDecl( CXXRecord, TTK_Struct, C, nullptr, SourceLocation(), SourceLocation(), nullptr, nullptr); - R->MayHaveOutOfDateDef = false; + R->setMayHaveOutOfDateDef(false); return R; } @@ -628,6 +628,24 @@ bool CXXRecordDecl::hasSubobjectAtOffsetZeroOfEmptyBaseType( return false; } +bool CXXRecordDecl::lambdaIsDefaultConstructibleAndAssignable() const { + assert(isLambda() && "not a lambda"); + + // C++2a [expr.prim.lambda.capture]p11: + // The closure type associated with a lambda-expression has no default + // constructor if the lambda-expression has a lambda-capture and a + // defaulted default constructor otherwise. It has a deleted copy + // assignment operator if the lambda-expression has a lambda-capture and + // defaulted copy and move assignment operators otherwise. + // + // C++17 [expr.prim.lambda]p21: + // The closure type associated with a lambda-expression has no default + // constructor and a deleted copy assignment operator. + if (getLambdaCaptureDefault() != LCD_None) + return false; + return getASTContext().getLangOpts().CPlusPlus2a; +} + void CXXRecordDecl::addedMember(Decl *D) { if (!D->isImplicit() && !isa<FieldDecl>(D) && @@ -731,9 +749,14 @@ void CXXRecordDecl::addedMember(Decl *D) { } // 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()) + // An aggregate is an array or a class with no user-provided [or] + // explicit [...] constructors + // C++20 [dcl.init.aggr]p1: + // An aggregate is an array or a class with no user-declared [...] + // constructors + if (getASTContext().getLangOpts().CPlusPlus2a + ? !Constructor->isImplicit() + : (Constructor->isUserProvided() || Constructor->isExplicit())) data().Aggregate = false; } @@ -1327,6 +1350,15 @@ bool CXXRecordDecl::isGenericLambda() const { return getLambdaData().IsGenericLambda; } +#ifndef NDEBUG +static bool allLookupResultsAreTheSame(const DeclContext::lookup_result &R) { + for (auto *D : R) + if (!declaresSameEntity(D, R.front())) + return false; + return true; +} +#endif + CXXMethodDecl* CXXRecordDecl::getLambdaCallOperator() const { if (!isLambda()) return nullptr; DeclarationName Name = @@ -1334,7 +1366,8 @@ CXXMethodDecl* CXXRecordDecl::getLambdaCallOperator() const { DeclContext::lookup_result Calls = lookup(Name); assert(!Calls.empty() && "Missing lambda call operator!"); - assert(Calls.size() == 1 && "More than one lambda call operator!"); + assert(allLookupResultsAreTheSame(Calls) && + "More than one lambda call operator!"); NamedDecl *CallOp = Calls.front(); if (const auto *CallOpTmpl = dyn_cast<FunctionTemplateDecl>(CallOp)) @@ -1349,7 +1382,8 @@ CXXMethodDecl* CXXRecordDecl::getLambdaStaticInvoker() const { &getASTContext().Idents.get(getLambdaStaticInvokerName()); DeclContext::lookup_result Invoker = lookup(Name); if (Invoker.empty()) return nullptr; - assert(Invoker.size() == 1 && "More than one static invoker operator!"); + assert(allLookupResultsAreTheSame(Invoker) && + "More than one static invoker operator!"); NamedDecl *InvokerFun = Invoker.front(); if (const auto *InvokerTemplate = dyn_cast<FunctionTemplateDecl>(InvokerFun)) return cast<CXXMethodDecl>(InvokerTemplate->getTemplatedDecl()); @@ -1994,7 +2028,9 @@ CXXMethodDecl *CXXMethodDecl::getDevirtualizedMethod(const Expr *Base, return nullptr; } -bool CXXMethodDecl::isUsualDeallocationFunction() const { +bool CXXMethodDecl::isUsualDeallocationFunction( + SmallVectorImpl<const FunctionDecl *> &PreventedBy) const { + assert(PreventedBy.empty() && "PreventedBy is expected to be empty"); if (getOverloadedOperator() != OO_Delete && getOverloadedOperator() != OO_Array_Delete) return false; @@ -2052,14 +2088,16 @@ bool CXXMethodDecl::isUsualDeallocationFunction() const { // This function is a usual deallocation function if there are no // single-parameter deallocation functions of the same kind. DeclContext::lookup_result R = getDeclContext()->lookup(getDeclName()); - for (DeclContext::lookup_result::iterator I = R.begin(), E = R.end(); - I != E; ++I) { - if (const auto *FD = dyn_cast<FunctionDecl>(*I)) - if (FD->getNumParams() == 1) - return false; + bool Result = true; + for (const auto *D : R) { + if (const auto *FD = dyn_cast<FunctionDecl>(D)) { + if (FD->getNumParams() == 1) { + PreventedBy.push_back(FD); + Result = false; + } + } } - - return true; + return Result; } bool CXXMethodDecl::isCopyAssignmentOperator() const { @@ -2135,19 +2173,24 @@ CXXMethodDecl::overridden_methods() const { return getASTContext().overridden_methods(this); } -QualType CXXMethodDecl::getThisType(ASTContext &C) const { +QualType CXXMethodDecl::getThisType(const FunctionProtoType *FPT, + const CXXRecordDecl *Decl) { + ASTContext &C = Decl->getASTContext(); + QualType ClassTy = C.getTypeDeclType(Decl); + ClassTy = C.getQualifiedType(ClassTy, FPT->getTypeQuals()); + return C.getPointerType(ClassTy); +} + +QualType CXXMethodDecl::getThisType() const { // C++ 9.3.2p1: The type of this in a member function of a class X is X*. // If the member function is declared const, the type of this is const X*, // if the member function is declared volatile, the type of this is // volatile X*, and if the member function is declared const volatile, // the type of this is const volatile X*. - assert(isInstance() && "No 'this' for static methods!"); - QualType ClassTy = C.getTypeDeclType(getParent()); - ClassTy = C.getQualifiedType(ClassTy, - Qualifiers::fromCVRUMask(getTypeQualifiers())); - return C.getPointerType(ClassTy); + return CXXMethodDecl::getThisType(getType()->getAs<FunctionProtoType>(), + getParent()); } bool CXXMethodDecl::hasInlineBody() const { @@ -2208,6 +2251,11 @@ CXXCtorInitializer::CXXCtorInitializer(ASTContext &Context, : Initializee(TInfo), Init(Init), LParenLoc(L), RParenLoc(R), IsDelegating(true), IsVirtual(false), IsWritten(false), SourceOrder(0) {} +int64_t CXXCtorInitializer::getID(const ASTContext &Context) const { + return Context.getAllocator() + .identifyKnownAlignedObject<CXXCtorInitializer>(this); +} + TypeLoc CXXCtorInitializer::getBaseClassLoc() const { if (isBaseInitializer()) return Initializee.get<TypeSourceInfo*>()->getTypeLoc(); @@ -2246,6 +2294,21 @@ SourceRange CXXCtorInitializer::getSourceRange() const { return SourceRange(getSourceLocation(), getRParenLoc()); } +CXXConstructorDecl::CXXConstructorDecl( + ASTContext &C, CXXRecordDecl *RD, SourceLocation StartLoc, + const DeclarationNameInfo &NameInfo, QualType T, TypeSourceInfo *TInfo, + bool isExplicitSpecified, bool isInline, bool isImplicitlyDeclared, + bool isConstexpr, InheritedConstructor Inherited) + : CXXMethodDecl(CXXConstructor, C, RD, StartLoc, NameInfo, T, TInfo, + SC_None, isInline, isConstexpr, SourceLocation()) { + setNumCtorInitializers(0); + setInheritingConstructor(static_cast<bool>(Inherited)); + setImplicit(isImplicitlyDeclared); + if (Inherited) + *getTrailingObjects<InheritedConstructor>() = Inherited; + setExplicitSpecified(isExplicitSpecified); +} + void CXXConstructorDecl::anchor() {} CXXConstructorDecl *CXXConstructorDecl::CreateDeserialized(ASTContext &C, @@ -2255,7 +2318,7 @@ CXXConstructorDecl *CXXConstructorDecl::CreateDeserialized(ASTContext &C, auto *Result = new (C, ID, Extra) CXXConstructorDecl( C, nullptr, SourceLocation(), DeclarationNameInfo(), QualType(), nullptr, false, false, false, false, InheritedConstructor()); - Result->IsInheritingConstructor = Inherited; + Result->setInheritingConstructor(Inherited); return Result; } @@ -2451,6 +2514,15 @@ bool CXXConversionDecl::isLambdaToBlockPointerConversion() const { getConversionType()->isBlockPointerType(); } +LinkageSpecDecl::LinkageSpecDecl(DeclContext *DC, SourceLocation ExternLoc, + SourceLocation LangLoc, LanguageIDs lang, + bool HasBraces) + : Decl(LinkageSpec, DC, LangLoc), DeclContext(LinkageSpec), + ExternLoc(ExternLoc), RBraceLoc(SourceLocation()) { + setLanguage(lang); + LinkageSpecDeclBits.HasBraces = HasBraces; +} + void LinkageSpecDecl::anchor() {} LinkageSpecDecl *LinkageSpecDecl::Create(ASTContext &C, @@ -2838,6 +2910,8 @@ void DecompositionDecl::printName(llvm::raw_ostream &os) const { os << ']'; } +void MSPropertyDecl::anchor() {} + MSPropertyDecl *MSPropertyDecl::Create(ASTContext &C, DeclContext *DC, SourceLocation L, DeclarationName N, QualType T, TypeSourceInfo *TInfo, |