diff options
Diffstat (limited to 'lib/AST')
-rw-r--r-- | lib/AST/ASTImporter.cpp | 28 | ||||
-rw-r--r-- | lib/AST/ASTStructuralEquivalence.cpp | 6 | ||||
-rw-r--r-- | lib/AST/Decl.cpp | 1 | ||||
-rw-r--r-- | lib/AST/DeclCXX.cpp | 109 | ||||
-rw-r--r-- | lib/AST/DeclPrinter.cpp | 22 |
5 files changed, 115 insertions, 51 deletions
diff --git a/lib/AST/ASTImporter.cpp b/lib/AST/ASTImporter.cpp index 300c3c9ada..004c466c8d 100644 --- a/lib/AST/ASTImporter.cpp +++ b/lib/AST/ASTImporter.cpp @@ -3047,11 +3047,20 @@ ExpectedDecl ASTNodeImporter::VisitFunctionDecl(FunctionDecl *D) { // Create the imported function. FunctionDecl *ToFunction = nullptr; if (auto *FromConstructor = dyn_cast<CXXConstructorDecl>(D)) { + Expr *ExplicitExpr = nullptr; + if (FromConstructor->getExplicitSpecifier().getExpr()) { + auto Imp = importSeq(FromConstructor->getExplicitSpecifier().getExpr()); + if (!Imp) + return Imp.takeError(); + std::tie(ExplicitExpr) = *Imp; + } if (GetImportedOrCreateDecl<CXXConstructorDecl>( - ToFunction, D, Importer.getToContext(), cast<CXXRecordDecl>(DC), - ToInnerLocStart, NameInfo, T, TInfo, - FromConstructor->isExplicit(), - D->isInlineSpecified(), D->isImplicit(), D->isConstexpr())) + ToFunction, D, Importer.getToContext(), cast<CXXRecordDecl>(DC), + ToInnerLocStart, NameInfo, T, TInfo, + ExplicitSpecifier( + ExplicitExpr, + FromConstructor->getExplicitSpecifier().getKind()), + D->isInlineSpecified(), D->isImplicit(), D->isConstexpr())) return ToFunction; } else if (CXXDestructorDecl *FromDtor = dyn_cast<CXXDestructorDecl>(D)) { @@ -3077,10 +3086,19 @@ ExpectedDecl ASTNodeImporter::VisitFunctionDecl(FunctionDecl *D) { ToDtor->setOperatorDelete(ToOperatorDelete, ToThisArg); } else if (CXXConversionDecl *FromConversion = dyn_cast<CXXConversionDecl>(D)) { + Expr *ExplicitExpr = nullptr; + if (FromConversion->getExplicitSpecifier().getExpr()) { + auto Imp = importSeq(FromConversion->getExplicitSpecifier().getExpr()); + if (!Imp) + return Imp.takeError(); + std::tie(ExplicitExpr) = *Imp; + } if (GetImportedOrCreateDecl<CXXConversionDecl>( ToFunction, D, Importer.getToContext(), cast<CXXRecordDecl>(DC), ToInnerLocStart, NameInfo, T, TInfo, D->isInlineSpecified(), - FromConversion->isExplicit(), D->isConstexpr(), SourceLocation())) + ExplicitSpecifier(ExplicitExpr, + FromConversion->getExplicitSpecifier().getKind()), + D->isConstexpr(), SourceLocation())) return ToFunction; } else if (auto *Method = dyn_cast<CXXMethodDecl>(D)) { if (GetImportedOrCreateDecl<CXXMethodDecl>( diff --git a/lib/AST/ASTStructuralEquivalence.cpp b/lib/AST/ASTStructuralEquivalence.cpp index 71bbd82481..f3c34d73bd 100644 --- a/lib/AST/ASTStructuralEquivalence.cpp +++ b/lib/AST/ASTStructuralEquivalence.cpp @@ -955,13 +955,15 @@ static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context, if (auto *Constructor1 = dyn_cast<CXXConstructorDecl>(Method1)) { auto *Constructor2 = cast<CXXConstructorDecl>(Method2); - if (Constructor1->isExplicit() != Constructor2->isExplicit()) + if (!Constructor1->getExplicitSpecifier().isEquivalent( + Constructor2->getExplicitSpecifier())) return false; } if (auto *Conversion1 = dyn_cast<CXXConversionDecl>(Method1)) { auto *Conversion2 = cast<CXXConversionDecl>(Method2); - if (Conversion1->isExplicit() != Conversion2->isExplicit()) + if (!Conversion1->getExplicitSpecifier().isEquivalent( + Conversion2->getExplicitSpecifier())) return false; if (!IsStructurallyEquivalent(Context, Conversion1->getConversionType(), Conversion2->getConversionType())) diff --git a/lib/AST/Decl.cpp b/lib/AST/Decl.cpp index 19fd3882bd..499a451380 100644 --- a/lib/AST/Decl.cpp +++ b/lib/AST/Decl.cpp @@ -2713,7 +2713,6 @@ FunctionDecl::FunctionDecl(Kind DK, ASTContext &C, DeclContext *DC, FunctionDeclBits.SClass = S; FunctionDeclBits.IsInline = isInlineSpecified; FunctionDeclBits.IsInlineSpecified = isInlineSpecified; - FunctionDeclBits.IsExplicitSpecified = false; FunctionDeclBits.IsVirtualAsWritten = false; FunctionDeclBits.IsPure = false; FunctionDeclBits.HasInheritedPrototype = false; diff --git a/lib/AST/DeclCXX.cpp b/lib/AST/DeclCXX.cpp index 4bd5ee1bb6..9946d16a85 100644 --- a/lib/AST/DeclCXX.cpp +++ b/lib/AST/DeclCXX.cpp @@ -1862,19 +1862,47 @@ bool CXXRecordDecl::mayBeAbstract() const { void CXXDeductionGuideDecl::anchor() {} +bool ExplicitSpecifier::isEquivalent(const ExplicitSpecifier Other) const { + if ((getKind() != Other.getKind() || + getKind() == ExplicitSpecKind::Unresolved)) { + if (getKind() == ExplicitSpecKind::Unresolved && + Other.getKind() == ExplicitSpecKind::Unresolved) { + ODRHash SelfHash, OtherHash; + SelfHash.AddStmt(getExpr()); + OtherHash.AddStmt(Other.getExpr()); + return SelfHash.CalculateHash() == OtherHash.CalculateHash(); + } else + return false; + } + return true; +} + +ExplicitSpecifier ExplicitSpecifier::getFromDecl(FunctionDecl *Function) { + switch (Function->getDeclKind()) { + case Decl::Kind::CXXConstructor: + return cast<CXXConstructorDecl>(Function)->getExplicitSpecifier(); + case Decl::Kind::CXXConversion: + return cast<CXXConversionDecl>(Function)->getExplicitSpecifier(); + case Decl::Kind::CXXDeductionGuide: + return cast<CXXDeductionGuideDecl>(Function)->getExplicitSpecifier(); + default: + return {}; + } +} + 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); + ASTContext &C, DeclContext *DC, SourceLocation StartLoc, + ExplicitSpecifier ES, const DeclarationNameInfo &NameInfo, QualType T, + TypeSourceInfo *TInfo, SourceLocation EndLocation) { + return new (C, DC) CXXDeductionGuideDecl(C, DC, StartLoc, ES, NameInfo, T, + TInfo, EndLocation); } CXXDeductionGuideDecl *CXXDeductionGuideDecl::CreateDeserialized(ASTContext &C, unsigned ID) { - return new (C, ID) CXXDeductionGuideDecl(C, nullptr, SourceLocation(), false, - DeclarationNameInfo(), QualType(), - nullptr, SourceLocation()); + return new (C, ID) CXXDeductionGuideDecl( + C, nullptr, SourceLocation(), ExplicitSpecifier(), DeclarationNameInfo(), + QualType(), nullptr, SourceLocation()); } void CXXMethodDecl::anchor() {} @@ -2312,47 +2340,54 @@ SourceRange CXXCtorInitializer::getSourceRange() const { CXXConstructorDecl::CXXConstructorDecl( ASTContext &C, CXXRecordDecl *RD, SourceLocation StartLoc, const DeclarationNameInfo &NameInfo, QualType T, TypeSourceInfo *TInfo, - bool isExplicitSpecified, bool isInline, bool isImplicitlyDeclared, + ExplicitSpecifier ES, 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); + CXXConstructorDeclBits.HasTrailingExplicitSpecifier = ES.getExpr() ? 1 : 0; if (Inherited) *getTrailingObjects<InheritedConstructor>() = Inherited; - setExplicitSpecified(isExplicitSpecified); + setExplicitSpecifier(ES); } void CXXConstructorDecl::anchor() {} CXXConstructorDecl *CXXConstructorDecl::CreateDeserialized(ASTContext &C, unsigned ID, - bool Inherited) { - unsigned Extra = additionalSizeToAlloc<InheritedConstructor>(Inherited); + uint64_t AllocKind) { + bool hasTraillingExplicit = static_cast<bool>(AllocKind & TAKHasTailExplicit); + bool isInheritingConstructor = + static_cast<bool>(AllocKind & TAKInheritsConstructor); + unsigned Extra = + additionalSizeToAlloc<InheritedConstructor, ExplicitSpecifier>( + isInheritingConstructor, hasTraillingExplicit); auto *Result = new (C, ID, Extra) CXXConstructorDecl( C, nullptr, SourceLocation(), DeclarationNameInfo(), QualType(), nullptr, - false, false, false, false, InheritedConstructor()); - Result->setInheritingConstructor(Inherited); + ExplicitSpecifier(), false, false, false, InheritedConstructor()); + Result->setInheritingConstructor(isInheritingConstructor); + Result->CXXConstructorDeclBits.HasTrailingExplicitSpecifier = + hasTraillingExplicit; + Result->setExplicitSpecifier(ExplicitSpecifier()); return Result; } -CXXConstructorDecl * -CXXConstructorDecl::Create(ASTContext &C, CXXRecordDecl *RD, - SourceLocation StartLoc, - const DeclarationNameInfo &NameInfo, - QualType T, TypeSourceInfo *TInfo, - bool isExplicit, bool isInline, - bool isImplicitlyDeclared, bool isConstexpr, - InheritedConstructor Inherited) { +CXXConstructorDecl *CXXConstructorDecl::Create( + ASTContext &C, CXXRecordDecl *RD, SourceLocation StartLoc, + const DeclarationNameInfo &NameInfo, QualType T, TypeSourceInfo *TInfo, + ExplicitSpecifier ES, bool isInline, bool isImplicitlyDeclared, + bool isConstexpr, InheritedConstructor Inherited) { assert(NameInfo.getName().getNameKind() == DeclarationName::CXXConstructorName && "Name must refer to a constructor"); unsigned Extra = - additionalSizeToAlloc<InheritedConstructor>(Inherited ? 1 : 0); - return new (C, RD, Extra) CXXConstructorDecl( - C, RD, StartLoc, NameInfo, T, TInfo, isExplicit, isInline, - isImplicitlyDeclared, isConstexpr, Inherited); + additionalSizeToAlloc<InheritedConstructor, ExplicitSpecifier>( + Inherited ? 1 : 0, ES.getExpr() ? 1 : 0); + return new (C, RD, Extra) + CXXConstructorDecl(C, RD, StartLoc, NameInfo, T, TInfo, ES, isInline, + isImplicitlyDeclared, isConstexpr, Inherited); } CXXConstructorDecl::init_const_iterator CXXConstructorDecl::init_begin() const { @@ -2503,25 +2538,21 @@ void CXXConversionDecl::anchor() {} CXXConversionDecl * CXXConversionDecl::CreateDeserialized(ASTContext &C, unsigned ID) { - return new (C, ID) CXXConversionDecl(C, nullptr, SourceLocation(), - DeclarationNameInfo(), QualType(), - nullptr, false, false, false, - SourceLocation()); + return new (C, ID) CXXConversionDecl( + C, nullptr, SourceLocation(), DeclarationNameInfo(), QualType(), nullptr, + false, ExplicitSpecifier(), false, SourceLocation()); } -CXXConversionDecl * -CXXConversionDecl::Create(ASTContext &C, CXXRecordDecl *RD, - SourceLocation StartLoc, - const DeclarationNameInfo &NameInfo, - QualType T, TypeSourceInfo *TInfo, - bool isInline, bool isExplicit, - bool isConstexpr, SourceLocation EndLocation) { +CXXConversionDecl *CXXConversionDecl::Create( + ASTContext &C, CXXRecordDecl *RD, SourceLocation StartLoc, + const DeclarationNameInfo &NameInfo, QualType T, TypeSourceInfo *TInfo, + bool isInline, ExplicitSpecifier ES, bool isConstexpr, + SourceLocation EndLocation) { assert(NameInfo.getName().getNameKind() == DeclarationName::CXXConversionFunctionName && "Name must refer to a conversion function"); return new (C, RD) CXXConversionDecl(C, RD, StartLoc, NameInfo, T, TInfo, - isInline, isExplicit, isConstexpr, - EndLocation); + isInline, ES, isConstexpr, EndLocation); } bool CXXConversionDecl::isLambdaToBlockPointerConversion() const { diff --git a/lib/AST/DeclPrinter.cpp b/lib/AST/DeclPrinter.cpp index c98ec3b85d..36c5d10f71 100644 --- a/lib/AST/DeclPrinter.cpp +++ b/lib/AST/DeclPrinter.cpp @@ -552,6 +552,21 @@ void DeclPrinter::VisitEnumConstantDecl(EnumConstantDecl *D) { } } +static void printExplicitSpecifier(ExplicitSpecifier ES, llvm::raw_ostream &Out, + PrintingPolicy &Policy, + unsigned Indentation) { + std::string Proto = "explicit"; + llvm::raw_string_ostream EOut(Proto); + if (ES.getExpr()) { + EOut << "("; + ES.getExpr()->printPretty(EOut, nullptr, Policy, Indentation); + EOut << ")"; + } + EOut << " "; + EOut.flush(); + Out << EOut.str(); +} + void DeclPrinter::VisitFunctionDecl(FunctionDecl *D) { if (!D->getDescribedFunctionTemplate() && !D->isFunctionTemplateSpecialization()) @@ -582,10 +597,9 @@ void DeclPrinter::VisitFunctionDecl(FunctionDecl *D) { if (D->isVirtualAsWritten()) Out << "virtual "; if (D->isModulePrivate()) Out << "__module_private__ "; if (D->isConstexpr() && !D->isExplicitlyDefaulted()) Out << "constexpr "; - if ((CDecl && CDecl->isExplicitSpecified()) || - (ConversionDecl && ConversionDecl->isExplicitSpecified()) || - (GuideDecl && GuideDecl->isExplicitSpecified())) - Out << "explicit "; + ExplicitSpecifier ExplicitSpec = ExplicitSpecifier::getFromDecl(D); + if (ExplicitSpec.isSpecified()) + printExplicitSpecifier(ExplicitSpec, Out, Policy, Indentation); } PrintingPolicy SubPolicy(Policy); |