diff options
Diffstat (limited to 'clang/lib')
-rw-r--r-- | clang/lib/AST/DeclBase.cpp | 1 | ||||
-rw-r--r-- | clang/lib/AST/DeclCXX.cpp | 17 | ||||
-rw-r--r-- | clang/lib/CodeGen/CGDecl.cpp | 1 | ||||
-rw-r--r-- | clang/lib/Sema/SemaDecl.cpp | 22 | ||||
-rw-r--r-- | clang/lib/Sema/SemaDeclCXX.cpp | 7 | ||||
-rw-r--r-- | clang/lib/Sema/SemaExpr.cpp | 3 | ||||
-rw-r--r-- | clang/lib/Sema/SemaInit.cpp | 21 | ||||
-rw-r--r-- | clang/lib/Sema/SemaOverload.cpp | 10 | ||||
-rw-r--r-- | clang/lib/Sema/SemaTemplate.cpp | 29 | ||||
-rw-r--r-- | clang/lib/Sema/SemaTemplateDeduction.cpp | 6 | ||||
-rw-r--r-- | clang/lib/Sema/SemaTemplateInstantiateDecl.cpp | 33 | ||||
-rw-r--r-- | clang/lib/Serialization/ASTCommon.cpp | 1 | ||||
-rw-r--r-- | clang/lib/Serialization/ASTReaderDecl.cpp | 8 | ||||
-rw-r--r-- | clang/lib/Serialization/ASTWriterDecl.cpp | 6 |
14 files changed, 102 insertions, 63 deletions
diff --git a/clang/lib/AST/DeclBase.cpp b/clang/lib/AST/DeclBase.cpp index 6111abab646..cda70c5edcd 100644 --- a/clang/lib/AST/DeclBase.cpp +++ b/clang/lib/AST/DeclBase.cpp @@ -619,6 +619,7 @@ bool Decl::isWeakImported() const { unsigned Decl::getIdentifierNamespaceForKind(Kind DeclKind) { switch (DeclKind) { case Function: + case CXXDeductionGuide: case CXXMethod: case CXXConstructor: case ConstructorUsingShadow: diff --git a/clang/lib/AST/DeclCXX.cpp b/clang/lib/AST/DeclCXX.cpp index a9db65a5151..fdfd6c07059 100644 --- a/clang/lib/AST/DeclCXX.cpp +++ b/clang/lib/AST/DeclCXX.cpp @@ -1472,6 +1472,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 { diff --git a/clang/lib/CodeGen/CGDecl.cpp b/clang/lib/CodeGen/CGDecl.cpp index b7c1743f62e..4ee8b98e67c 100644 --- a/clang/lib/CodeGen/CGDecl.cpp +++ b/clang/lib/CodeGen/CGDecl.cpp @@ -50,6 +50,7 @@ void CodeGenFunction::EmitDecl(const Decl &D) { case Decl::TemplateTypeParm: case Decl::UnresolvedUsingValue: case Decl::NonTypeTemplateParm: + case Decl::CXXDeductionGuide: case Decl::CXXMethod: case Decl::CXXConstructor: case Decl::CXXDestructor: diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp index 3905348d3ca..77d74983028 100644 --- a/clang/lib/Sema/SemaDecl.cpp +++ b/clang/lib/Sema/SemaDecl.cpp @@ -7658,14 +7658,9 @@ static FunctionDecl* CreateNewFunctionDecl(Sema &SemaRef, Declarator &D, } else if (Name.getNameKind() == DeclarationName::CXXDeductionGuideName) { SemaRef.CheckDeductionGuideDeclarator(D, R, SC); - // We don't need to store much extra information for a deduction guide, so - // just model it as a plain FunctionDecl. - auto *FD = FunctionDecl::Create(SemaRef.Context, DC, D.getLocStart(), - NameInfo, R, TInfo, SC, isInline, - true /*HasPrototype*/, isConstexpr); - if (isExplicit) - FD->setExplicitSpecified(); - return FD; + return CXXDeductionGuideDecl::Create(SemaRef.Context, DC, D.getLocStart(), + isExplicit, NameInfo, R, TInfo, + D.getLocEnd()); } else if (DC->isRecord()) { // If the name of the function is the same as the name of the record, // then this must be an invalid constructor that has a return type. @@ -8154,7 +8149,8 @@ Sema::ActOnFunctionDeclarator(Scope *S, Declarator &D, DeclContext *DC, // The explicit specifier shall be used only in the declaration of a // constructor or conversion function within its class definition; // see 12.3.1 and 12.3.2. - if (isExplicit && !NewFD->isInvalidDecl() && !NewFD->isDeductionGuide()) { + if (isExplicit && !NewFD->isInvalidDecl() && + !isa<CXXDeductionGuideDecl>(NewFD)) { if (!CurContext->isRecord()) { // 'explicit' was specified outside of the class. Diag(D.getDeclSpec().getExplicitSpecLoc(), @@ -9152,14 +9148,14 @@ bool Sema::CheckFunctionDeclaration(Scope *S, FunctionDecl *NewFD, } else if (CXXConversionDecl *Conversion = dyn_cast<CXXConversionDecl>(NewFD)) { ActOnConversionDeclarator(Conversion); - } else if (NewFD->isDeductionGuide()) { - if (auto *TD = NewFD->getDescribedFunctionTemplate()) + } else if (auto *Guide = dyn_cast<CXXDeductionGuideDecl>(NewFD)) { + if (auto *TD = Guide->getDescribedFunctionTemplate()) CheckDeductionGuideTemplate(TD); // A deduction guide is not on the list of entities that can be // explicitly specialized. - if (NewFD->getTemplateSpecializationKind() == TSK_ExplicitSpecialization) - Diag(NewFD->getLocStart(), diag::err_deduction_guide_specialized) + if (Guide->getTemplateSpecializationKind() == TSK_ExplicitSpecialization) + Diag(Guide->getLocStart(), diag::err_deduction_guide_specialized) << /*explicit specialization*/ 1; } diff --git a/clang/lib/Sema/SemaDeclCXX.cpp b/clang/lib/Sema/SemaDeclCXX.cpp index 6887962940e..d28354f6e82 100644 --- a/clang/lib/Sema/SemaDeclCXX.cpp +++ b/clang/lib/Sema/SemaDeclCXX.cpp @@ -650,10 +650,11 @@ bool Sema::MergeCXXFunctionDecl(FunctionDecl *New, FunctionDecl *Old, // FIXME: It's not clear what should happen if multiple declarations of a // deduction guide have different explicitness. For now at least we simply // reject any case where the explicitness changes. - if (New->isDeductionGuide() && - New->isExplicitSpecified() != Old->isExplicitSpecified()) { + auto *NewGuide = dyn_cast<CXXDeductionGuideDecl>(New); + if (NewGuide && NewGuide->isExplicitSpecified() != + cast<CXXDeductionGuideDecl>(Old)->isExplicitSpecified()) { Diag(New->getLocation(), diag::err_deduction_guide_explicit_mismatch) - << New->isExplicitSpecified(); + << NewGuide->isExplicitSpecified(); Diag(Old->getLocation(), diag::note_previous_declaration); } diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp index e76a8b6da0f..d628b9898a9 100644 --- a/clang/lib/Sema/SemaExpr.cpp +++ b/clang/lib/Sema/SemaExpr.cpp @@ -3036,6 +3036,9 @@ ExprResult Sema::BuildDeclarationNameExpr( break; } + case Decl::CXXDeductionGuide: + llvm_unreachable("building reference to deduction guide"); + case Decl::MSProperty: valueKind = VK_LValue; break; diff --git a/clang/lib/Sema/SemaInit.cpp b/clang/lib/Sema/SemaInit.cpp index 151b974b410..6d20b01e4e1 100644 --- a/clang/lib/Sema/SemaInit.cpp +++ b/clang/lib/Sema/SemaInit.cpp @@ -8296,10 +8296,10 @@ QualType Sema::DeduceTemplateSpecializationFromInitializer( if (D->isInvalidDecl()) continue; - FunctionTemplateDecl *TD = dyn_cast<FunctionTemplateDecl>(D); - FunctionDecl *FD = - TD ? TD->getTemplatedDecl() : dyn_cast<FunctionDecl>(D); - if (!FD) + auto *TD = dyn_cast<FunctionTemplateDecl>(D); + auto *GD = dyn_cast_or_null<CXXDeductionGuideDecl>( + TD ? TD->getTemplatedDecl() : dyn_cast<FunctionDecl>(D)); + if (!GD) continue; // C++ [over.match.ctor]p1: (non-list copy-initialization from non-class) @@ -8309,21 +8309,21 @@ QualType Sema::DeduceTemplateSpecializationFromInitializer( // The converting constructors of T are candidate functions. if (Kind.isCopyInit() && !ListInit) { // Only consider converting constructors. - if (FD->isExplicit()) + if (GD->isExplicit()) continue; // When looking for a converting constructor, deduction guides that // could never be called with one argument are not interesting to // check or note. - if (FD->getMinRequiredArguments() > 1 || - (FD->getNumParams() == 0 && !FD->isVariadic())) + if (GD->getMinRequiredArguments() > 1 || + (GD->getNumParams() == 0 && !GD->isVariadic())) continue; } // C++ [over.match.list]p1.1: (first phase list initialization) // Initially, the candidate functions are the initializer-list // constructors of the class T - if (OnlyListConstructors && !isInitListConstructor(FD)) + if (OnlyListConstructors && !isInitListConstructor(GD)) continue; // C++ [over.match.list]p1.2: (second phase list initialization) @@ -8345,7 +8345,7 @@ QualType Sema::DeduceTemplateSpecializationFromInitializer( Inits, Candidates, SuppressUserConversions); else - AddOverloadCandidate(FD, I.getPair(), Inits, Candidates, + AddOverloadCandidate(GD, I.getPair(), Inits, Candidates, SuppressUserConversions); } return Candidates.BestViableFunction(*this, Kind.getLocation(), Best); @@ -8416,7 +8416,8 @@ QualType Sema::DeduceTemplateSpecializationFromInitializer( // C++ [over.match.list]p1: // In copy-list-initialization, if an explicit constructor is chosen, the // initialization is ill-formed. - if (Kind.isCopyInit() && ListInit && Best->Function->isExplicit()) { + if (Kind.isCopyInit() && ListInit && + cast<CXXDeductionGuideDecl>(Best->Function)->isExplicit()) { bool IsDeductionGuide = !Best->Function->isImplicit(); Diag(Kind.getLocation(), diag::err_deduced_class_template_explicit) << TemplateName << IsDeductionGuide; diff --git a/clang/lib/Sema/SemaOverload.cpp b/clang/lib/Sema/SemaOverload.cpp index 659d6226f3b..32a03a57ca3 100644 --- a/clang/lib/Sema/SemaOverload.cpp +++ b/clang/lib/Sema/SemaOverload.cpp @@ -8992,12 +8992,10 @@ bool clang::isBetterOverloadCandidate(Sema &S, const OverloadCandidate &Cand1, } // -- F1 is generated from a deduction-guide and F2 is not - if (Cand1.Function && Cand2.Function && Cand1.Function->isDeductionGuide() && - Cand1.Function->isImplicit() != Cand2.Function->isImplicit()) { - assert(Cand2.Function->isDeductionGuide() && - "comparing deduction guide with non-deduction-guide"); - return Cand2.Function->isImplicit(); - } + auto *Guide1 = dyn_cast_or_null<CXXDeductionGuideDecl>(Cand1.Function); + auto *Guide2 = dyn_cast_or_null<CXXDeductionGuideDecl>(Cand2.Function); + if (Guide1 && Guide2 && Guide1->isImplicit() != Guide2->isImplicit()) + return Guide2->isImplicit(); // -- F1 is a non-template function and F2 is a function template // specialization, or, if not that, diff --git a/clang/lib/Sema/SemaTemplate.cpp b/clang/lib/Sema/SemaTemplate.cpp index 4c5f3bee15b..e05f3fe36d9 100644 --- a/clang/lib/Sema/SemaTemplate.cpp +++ b/clang/lib/Sema/SemaTemplate.cpp @@ -1438,7 +1438,8 @@ struct ConvertConstructorToDeductionGuideTransform { unsigned Depth1IndexAdjustment = Template->getTemplateParameters()->size(); /// Transform a constructor declaration into a deduction guide. - NamedDecl *transformConstructor(FunctionTemplateDecl *FTD, FunctionDecl *FD) { + NamedDecl *transformConstructor(FunctionTemplateDecl *FTD, + CXXConstructorDecl *CD) { SmallVector<TemplateArgument, 16> SubstArgs; // C++ [over.match.class.deduct]p1: @@ -1485,7 +1486,7 @@ struct ConvertConstructorToDeductionGuideTransform { Args.addOuterTemplateArguments(None); } - FunctionProtoTypeLoc FPTL = FD->getTypeSourceInfo()->getTypeLoc() + FunctionProtoTypeLoc FPTL = CD->getTypeSourceInfo()->getTypeLoc() .getAsAdjusted<FunctionProtoTypeLoc>(); assert(FPTL && "no prototype for constructor declaration"); @@ -1499,9 +1500,9 @@ struct ConvertConstructorToDeductionGuideTransform { return nullptr; TypeSourceInfo *NewTInfo = TLB.getTypeSourceInfo(SemaRef.Context, NewType); - return buildDeductionGuide(TemplateParams, FD->isExplicit(), NewTInfo, - FD->getLocStart(), FD->getLocation(), - FD->getLocEnd()); + return buildDeductionGuide(TemplateParams, CD->isExplicit(), NewTInfo, + CD->getLocStart(), CD->getLocation(), + CD->getLocEnd()); } /// Build a deduction guide with the specified parameter types. @@ -1677,17 +1678,15 @@ private: bool Explicit, TypeSourceInfo *TInfo, SourceLocation LocStart, SourceLocation Loc, SourceLocation LocEnd) { + DeclarationNameInfo Name(DeductionGuideName, Loc); ArrayRef<ParmVarDecl *> Params = TInfo->getTypeLoc().castAs<FunctionProtoTypeLoc>().getParams(); // Build the implicit deduction guide template. - auto *Guide = FunctionDecl::Create(SemaRef.Context, DC, LocStart, Loc, - DeductionGuideName, TInfo->getType(), - TInfo, SC_None); + auto *Guide = + CXXDeductionGuideDecl::Create(SemaRef.Context, DC, LocStart, Explicit, + Name, TInfo->getType(), TInfo, LocEnd); Guide->setImplicit(); - if (Explicit) - Guide->setExplicitSpecified(); - Guide->setRangeEnd(LocEnd); Guide->setParams(Params); for (auto *Param : Params) @@ -1749,16 +1748,16 @@ void Sema::DeclareImplicitDeductionGuides(TemplateDecl *Template, D = cast<NamedDecl>(D->getCanonicalDecl()); auto *FTD = dyn_cast<FunctionTemplateDecl>(D); - auto *FD = FTD ? FTD->getTemplatedDecl() : dyn_cast<FunctionDecl>(D); + auto *CD = + dyn_cast_or_null<CXXConstructorDecl>(FTD ? FTD->getTemplatedDecl() : D); // Class-scope explicit specializations (MS extension) do not result in // deduction guides. - if (!FD || (!FTD && FD->isFunctionTemplateSpecialization())) + if (!CD || (!FTD && CD->isFunctionTemplateSpecialization())) continue; - Transform.transformConstructor(FTD, FD); + Transform.transformConstructor(FTD, CD); AddedAny = true; - CXXConstructorDecl *CD = cast<CXXConstructorDecl>(FD); AddedCopyOrMove |= CD->isCopyOrMoveConstructor(); } diff --git a/clang/lib/Sema/SemaTemplateDeduction.cpp b/clang/lib/Sema/SemaTemplateDeduction.cpp index 5d78fd437e2..6c3a618fbb9 100644 --- a/clang/lib/Sema/SemaTemplateDeduction.cpp +++ b/clang/lib/Sema/SemaTemplateDeduction.cpp @@ -968,10 +968,10 @@ bool Sema::isSameOrCompatibleFunctionType(CanQualType Param, /// the template parameter lists of a class template and a constructor template /// when forming an implicit deduction guide. static unsigned getFirstInnerIndex(FunctionTemplateDecl *FTD) { - if (!FTD->isImplicit() || !FTD->getTemplatedDecl()->isDeductionGuide()) + auto *Guide = dyn_cast<CXXDeductionGuideDecl>(FTD->getTemplatedDecl()); + if (!Guide || !Guide->isImplicit()) return 0; - return FTD->getDeclName().getCXXDeductionGuideTemplate() - ->getTemplateParameters()->size(); + return Guide->getDeducedTemplate()->getTemplateParameters()->size(); } /// Determine whether a type denotes a forwarding reference. diff --git a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp index f7db189de84..63c10c0c712 100644 --- a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp +++ b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp @@ -1599,21 +1599,22 @@ Decl *TemplateDeclInstantiator::VisitFunctionDecl(FunctionDecl *D, TemplateArgs); } - FunctionDecl *Function = - FunctionDecl::Create(SemaRef.Context, DC, D->getInnerLocStart(), - D->getNameInfo(), T, TInfo, - D->getCanonicalDecl()->getStorageClass(), - D->isInlineSpecified(), D->hasWrittenPrototype(), - D->isConstexpr()); - Function->setRangeEnd(D->getSourceRange().getEnd()); + FunctionDecl *Function; + if (auto *DGuide = dyn_cast<CXXDeductionGuideDecl>(D)) + Function = CXXDeductionGuideDecl::Create( + SemaRef.Context, DC, D->getInnerLocStart(), DGuide->isExplicit(), + D->getNameInfo(), T, TInfo, D->getSourceRange().getEnd()); + else { + Function = FunctionDecl::Create( + SemaRef.Context, DC, D->getInnerLocStart(), D->getNameInfo(), T, TInfo, + D->getCanonicalDecl()->getStorageClass(), D->isInlineSpecified(), + D->hasWrittenPrototype(), D->isConstexpr()); + Function->setRangeEnd(D->getSourceRange().getEnd()); + } if (D->isInlined()) Function->setImplicitlyInline(); - // A deduction-guide could be explicit. - if (D->isExplicitSpecified()) - Function->setExplicitSpecified(); - if (QualifierLoc) Function->setQualifierInfo(QualifierLoc); @@ -2781,6 +2782,11 @@ Decl *TemplateDeclInstantiator::VisitFunctionDecl(FunctionDecl *D) { return VisitFunctionDecl(D, nullptr); } +Decl * +TemplateDeclInstantiator::VisitCXXDeductionGuideDecl(CXXDeductionGuideDecl *D) { + return VisitFunctionDecl(D, nullptr); +} + Decl *TemplateDeclInstantiator::VisitCXXMethodDecl(CXXMethodDecl *D) { return VisitCXXMethodDecl(D, nullptr); } @@ -4958,8 +4964,9 @@ NamedDecl *Sema::FindInstantiatedDecl(SourceLocation Loc, NamedDecl *D, } // An implicit deduction guide acts as if it's within the class template // specialization described by its name and first N template params. - if (FD->isDeductionGuide() && FD->isImplicit()) { - TemplateDecl *TD = FD->getDeclName().getCXXDeductionGuideTemplate(); + auto *Guide = dyn_cast<CXXDeductionGuideDecl>(FD); + if (Guide && Guide->isImplicit()) { + TemplateDecl *TD = Guide->getDeducedTemplate(); TemplateArgumentListInfo Args(Loc, Loc); for (auto Arg : TemplateArgs.getInnermost().take_front( TD->getTemplateParameters()->size())) diff --git a/clang/lib/Serialization/ASTCommon.cpp b/clang/lib/Serialization/ASTCommon.cpp index 65792c7e4df..684ec243035 100644 --- a/clang/lib/Serialization/ASTCommon.cpp +++ b/clang/lib/Serialization/ASTCommon.cpp @@ -251,6 +251,7 @@ bool serialization::isRedeclarableDeclKind(unsigned Kind) { case Decl::VarTemplateSpecialization: case Decl::VarTemplatePartialSpecialization: case Decl::Function: + case Decl::CXXDeductionGuide: case Decl::CXXMethod: case Decl::CXXConstructor: case Decl::CXXDestructor: diff --git a/clang/lib/Serialization/ASTReaderDecl.cpp b/clang/lib/Serialization/ASTReaderDecl.cpp index 9be3981329a..add3b3e828e 100644 --- a/clang/lib/Serialization/ASTReaderDecl.cpp +++ b/clang/lib/Serialization/ASTReaderDecl.cpp @@ -293,6 +293,7 @@ namespace clang { void VisitUnresolvedUsingValueDecl(UnresolvedUsingValueDecl *D); void VisitDeclaratorDecl(DeclaratorDecl *DD); void VisitFunctionDecl(FunctionDecl *FD); + void VisitCXXDeductionGuideDecl(CXXDeductionGuideDecl *GD); void VisitCXXMethodDecl(CXXMethodDecl *D); void VisitCXXConstructorDecl(CXXConstructorDecl *D); void VisitCXXDestructorDecl(CXXDestructorDecl *D); @@ -1786,6 +1787,10 @@ ASTDeclReader::VisitCXXRecordDeclImpl(CXXRecordDecl *D) { return Redecl; } +void ASTDeclReader::VisitCXXDeductionGuideDecl(CXXDeductionGuideDecl *D) { + VisitFunctionDecl(D); +} + void ASTDeclReader::VisitCXXMethodDecl(CXXMethodDecl *D) { VisitFunctionDecl(D); @@ -3371,6 +3376,9 @@ Decl *ASTReader::ReadDeclRecord(DeclID ID) { case DECL_CXX_RECORD: D = CXXRecordDecl::CreateDeserialized(Context, ID); break; + case DECL_CXX_DEDUCTION_GUIDE: + D = CXXDeductionGuideDecl::CreateDeserialized(Context, ID); + break; case DECL_CXX_METHOD: D = CXXMethodDecl::CreateDeserialized(Context, ID); break; diff --git a/clang/lib/Serialization/ASTWriterDecl.cpp b/clang/lib/Serialization/ASTWriterDecl.cpp index 3144b87cd45..200be6688b0 100644 --- a/clang/lib/Serialization/ASTWriterDecl.cpp +++ b/clang/lib/Serialization/ASTWriterDecl.cpp @@ -86,6 +86,7 @@ namespace clang { void VisitUnresolvedUsingValueDecl(UnresolvedUsingValueDecl *D); void VisitDeclaratorDecl(DeclaratorDecl *D); void VisitFunctionDecl(FunctionDecl *D); + void VisitCXXDeductionGuideDecl(CXXDeductionGuideDecl *D); void VisitCXXMethodDecl(CXXMethodDecl *D); void VisitCXXConstructorDecl(CXXConstructorDecl *D); void VisitCXXDestructorDecl(CXXDestructorDecl *D); @@ -609,6 +610,11 @@ void ASTDeclWriter::VisitFunctionDecl(FunctionDecl *D) { Code = serialization::DECL_FUNCTION; } +void ASTDeclWriter::VisitCXXDeductionGuideDecl(CXXDeductionGuideDecl *D) { + VisitFunctionDecl(D); + Code = serialization::DECL_CXX_DEDUCTION_GUIDE; +} + void ASTDeclWriter::VisitObjCMethodDecl(ObjCMethodDecl *D) { VisitNamedDecl(D); // FIXME: convert to LazyStmtPtr? |