44#include "llvm/ADT/APInt.h"
45#include "llvm/ADT/APSInt.h"
46#include "llvm/ADT/ArrayRef.h"
47#include "llvm/ADT/DenseMap.h"
48#include "llvm/ADT/FoldingSet.h"
49#include "llvm/ADT/SmallBitVector.h"
50#include "llvm/ADT/SmallPtrSet.h"
51#include "llvm/ADT/SmallVector.h"
52#include "llvm/Support/Casting.h"
53#include "llvm/Support/Compiler.h"
54#include "llvm/Support/ErrorHandling.h"
112using namespace clang;
118 if (Y.getBitWidth() >
X.getBitWidth())
119 X =
X.extend(Y.getBitWidth());
120 else if (Y.getBitWidth() <
X.getBitWidth())
121 Y = Y.extend(
X.getBitWidth());
124 if (
X.isSigned() != Y.isSigned()) {
126 if ((Y.isSigned() && Y.isNegative()) || (
X.isSigned() &&
X.isNegative()))
148 bool NumberOfArgumentsMustMatch);
152 bool OnlyDeduced,
unsigned Depth,
153 llvm::SmallBitVector &
Used);
156 bool OnlyDeduced,
unsigned Level,
157 llvm::SmallBitVector &Deduced);
167 if (
const auto *IC = dyn_cast<ImplicitCastExpr>(E))
168 E = IC->getSubExpr();
169 else if (
const auto *CE = dyn_cast<ConstantExpr>(E))
170 E = CE->getSubExpr();
171 else if (
const auto *Subst = dyn_cast<SubstNonTypeTemplateParmExpr>(E))
172 E = Subst->getReplacement();
173 else if (
const auto *CCE = dyn_cast<CXXConstructExpr>(E)) {
175 if (CCE->getParenOrBraceRange().isValid())
178 assert(CCE->getNumArgs() >= 1 &&
"implicit construct expr should have 1 arg");
184 if (
const auto *DRE = dyn_cast<DeclRefExpr>(E))
185 if (
const auto *NTTP = dyn_cast<NonTypeTemplateParmDecl>(DRE->getDecl()))
186 if (NTTP->getDepth() == Depth)
201 X = NX->getUnderlyingDecl();
202 if (
NamedDecl *NY = dyn_cast<NamedDecl>(Y))
203 Y = NY->getUnderlyingDecl();
216 bool AggregateCandidateDeduction =
false) {
229 QualType XType =
X.getNonTypeTemplateArgumentType();
237 switch (
X.getKind()) {
239 llvm_unreachable(
"Non-deduced template arguments handled above");
246 X.wasDeducedFromArrayBound() ||
252 return X.wasDeducedFromArrayBound() ? Y :
X;
266 return X.wasDeducedFromArrayBound() ? Y :
X;
275 X.structurallyEquals(Y)))
303 llvm::FoldingSetNodeID ID1, ID2;
304 X.getAsExpr()->Profile(ID1, Context,
true);
307 return X.wasDeducedFromArrayBound() ? Y :
X;
314 assert(!
X.wasDeducedFromArrayBound());
327 X.getParamTypeForDecl());
364 (!AggregateCandidateDeduction &&
X.pack_size() != Y.
pack_size()))
371 XA != XAEnd; ++XA, ++YA) {
376 if (Merged.isNull() && !(XA->isNull() && YA->isNull()))
378 NewPack.push_back(Merged);
380 NewPack.push_back(*XA);
390 llvm_unreachable(
"Invalid TemplateArgument Kind!");
403 "deducing non-type template argument with wrong depth");
407 if (Result.isNull()) {
411 return TemplateDeductionResult::Inconsistent;
416 return TemplateDeductionResult::Success;
423 return TemplateDeductionResult::Success;
428 if (
auto *Expansion = dyn_cast<PackExpansionType>(ParamType))
429 ParamType = Expansion->getPattern();
443 S, TemplateParams, ParamType, ValueType, Info, Deduced,
456 S, TemplateParams, NTTP,
458 DeducedFromArrayBound),
459 ValueType, Info, Deduced);
519 return TemplateDeductionResult::Success;
523 = dyn_cast<TemplateTemplateParmDecl>(ParamDecl)) {
526 return TemplateDeductionResult::Success;
530 Deduced[TempParam->getIndex()],
532 if (Result.isNull()) {
533 Info.
Param = TempParam;
534 Info.
FirstArg = Deduced[TempParam->getIndex()];
536 return TemplateDeductionResult::Inconsistent;
539 Deduced[TempParam->getIndex()] = Result;
540 return TemplateDeductionResult::Success;
545 return TemplateDeductionResult::Success;
550 return TemplateDeductionResult::NonDeducedMismatch;
578 UP = IP->getInjectedSpecializationType();
585 if (
const auto *TD = TNP.getAsTemplateDecl(); TD && TD->isTypeAlias())
586 return TemplateDeductionResult::Success;
593 UA = Injected->getInjectedSpecializationType();
603 return TemplateDeductionResult::Success;
608 Result != TemplateDeductionResult::Success)
614 SA->template_arguments(), Info, Deduced,
623 RA ? dyn_cast<ClassTemplateSpecializationDecl>(RA->getDecl()) :
nullptr;
627 return TemplateDeductionResult::NonDeducedMismatch;
632 S, TemplateParams, TP->getTemplateName(),
633 TemplateName(SA->getSpecializedTemplate()), Info, Deduced);
634 Result != TemplateDeductionResult::Success)
639 SA->getTemplateArgs().asArray(), Info, Deduced,
647 case Type::TypeOfExpr:
649 case Type::DependentName:
651 case Type::PackIndexing:
652 case Type::UnresolvedUsing:
653 case Type::TemplateTypeParm:
657 case Type::ConstantArray:
658 case Type::IncompleteArray:
659 case Type::VariableArray:
660 case Type::DependentSizedArray:
662 cast<ArrayType>(
T)->getElementType().getTypePtr());
711class PackDeductionScope {
717 bool DeducePackIfNotAlreadyDeduced =
false)
718 : S(S), TemplateParams(TemplateParams), Deduced(Deduced), Info(Info),
719 DeducePackIfNotAlreadyDeduced(DeducePackIfNotAlreadyDeduced){
720 unsigned NumNamedPacks = addPacks(Pattern);
721 finishConstruction(NumNamedPacks);
728 : S(S), TemplateParams(TemplateParams), Deduced(Deduced), Info(Info) {
730 finishConstruction(1);
734 void addPack(
unsigned Index) {
737 DeducedFromEarlierParameter = !Deduced[Index].isNull();
739 Pack.Saved = Deduced[Index];
745 if (std::optional<unsigned> ExpandedPackExpansions =
747 FixedNumExpansions = ExpandedPackExpansions;
749 Packs.push_back(Pack);
755 llvm::SmallBitVector SawIndices(TemplateParams->size());
758 auto AddPack = [&](
unsigned Index) {
759 if (SawIndices[Index])
761 SawIndices[Index] =
true;
768 if (
auto *NTTP = dyn_cast<NonTypeTemplateParmDecl>(
769 TemplateParams->getParam(Index))) {
770 if (!NTTP->isExpandedParameterPack())
771 if (
auto *Expansion = dyn_cast<PackExpansionType>(NTTP->getType()))
772 ExtraDeductions.push_back(Expansion->getPattern());
781 for (
unsigned I = 0, N = Unexpanded.size(); I != N; ++I) {
782 unsigned Depth, Index;
784 if (Depth == Info.getDeducedDepth())
791 assert(!Packs.empty() &&
"Pack expansion without unexpanded packs?");
793 unsigned NumNamedPacks = Packs.size();
797 while (!ExtraDeductions.empty())
798 Collect(ExtraDeductions.pop_back_val());
800 return NumNamedPacks;
803 void finishConstruction(
unsigned NumNamedPacks) {
806 unsigned NumPartialPackArgs = 0;
807 std::pair<unsigned, unsigned> PartialPackDepthIndex(-1u, -1u);
809 if (
auto *Partial =
Scope->getPartiallySubstitutedPack(
810 &PartialPackArgs, &NumPartialPackArgs))
816 bool IsExpanded =
true;
817 for (
unsigned I = 0; I != NumNamedPacks; ++I) {
818 if (Packs[I].Index >= Info.getNumExplicitArgs()) {
820 IsPartiallyExpanded =
false;
823 if (PartialPackDepthIndex ==
824 std::make_pair(Info.getDeducedDepth(), Packs[I].Index)) {
825 IsPartiallyExpanded =
true;
831 if (IsPartiallyExpanded)
832 PackElements += NumPartialPackArgs;
834 PackElements += *FixedNumExpansions;
836 for (
auto &Pack : Packs) {
837 if (Info.PendingDeducedPacks.size() > Pack.Index)
838 Pack.Outer = Info.PendingDeducedPacks[Pack.Index];
840 Info.PendingDeducedPacks.resize(Pack.Index + 1);
841 Info.PendingDeducedPacks[Pack.Index] = &Pack;
843 if (PartialPackDepthIndex ==
844 std::make_pair(Info.getDeducedDepth(), Pack.Index)) {
845 Pack.New.append(PartialPackArgs, PartialPackArgs + NumPartialPackArgs);
854 if (!IsPartiallyExpanded)
855 Deduced[Pack.Index] = Pack.New[PackElements];
861 ~PackDeductionScope() {
862 for (
auto &Pack : Packs)
863 Info.PendingDeducedPacks[Pack.Index] = Pack.Outer;
867 std::optional<unsigned> getSavedPackSizeIfAllEqual()
const {
868 unsigned PackSize = Packs[0].Saved.pack_size();
870 if (std::all_of(Packs.begin() + 1, Packs.end(), [&PackSize](
const auto &
P) {
871 return P.Saved.pack_size() == PackSize;
879 bool isDeducedFromEarlierParameter()
const {
880 return DeducedFromEarlierParameter;
885 bool isPartiallyExpanded() {
return IsPartiallyExpanded; }
890 bool hasFixedArity() {
return FixedNumExpansions.has_value(); }
895 bool hasNextElement() {
896 return !FixedNumExpansions || *FixedNumExpansions > PackElements;
900 void nextPackElement() {
904 for (
auto &Pack : Packs) {
906 if (!Pack.New.empty() || !DeducedArg.
isNull()) {
907 while (Pack.New.size() < PackElements)
909 if (Pack.New.size() == PackElements)
910 Pack.New.push_back(DeducedArg);
912 Pack.New[PackElements] = DeducedArg;
913 DeducedArg = Pack.New.size() > PackElements + 1
914 ? Pack.New[PackElements + 1]
927 for (
auto &Pack : Packs) {
929 Deduced[Pack.Index] = Pack.Saved;
944 Pack.New.resize(PackElements);
948 if (Pack.New.empty()) {
954 std::copy(Pack.New.begin(), Pack.New.end(), ArgumentPack);
962 Pack.New[0].wasDeducedFromArrayBound());
968 if (Pack.Outer->DeferredDeduction.isNull()) {
971 Pack.Outer->DeferredDeduction = NewPack;
974 Loc = &Pack.Outer->DeferredDeduction;
976 Loc = &Deduced[Pack.Index];
982 S.
Context, OldPack, NewPack, DeducePackIfNotAlreadyDeduced);
984 Info.AggregateDeductionCandidateHasMismatchedArity =
990 if (!Result.isNull() && !Pack.DeferredDeduction.isNull()) {
992 NewPack = Pack.DeferredDeduction;
996 NamedDecl *Param = TemplateParams->getParam(Pack.Index);
997 if (Result.isNull()) {
999 Info.FirstArg = OldPack;
1000 Info.SecondArg = NewPack;
1001 return TemplateDeductionResult::Inconsistent;
1007 if (*Expansions != PackElements) {
1009 Info.FirstArg = Result;
1010 return TemplateDeductionResult::IncompletePack;
1017 return TemplateDeductionResult::Success;
1025 unsigned PackElements = 0;
1026 bool IsPartiallyExpanded =
false;
1027 bool DeducePackIfNotAlreadyDeduced =
false;
1028 bool DeducedFromEarlierParameter =
false;
1030 std::optional<unsigned> FixedNumExpansions;
1069 const QualType *Params,
unsigned NumParams,
1070 const QualType *Args,
unsigned NumArgs,
1083 = dyn_cast<PackExpansionType>(Params[
ParamIdx]);
1088 if (ArgIdx >= NumArgs)
1089 return TemplateDeductionResult::MiscellaneousDeductionFailure;
1091 if (isa<PackExpansionType>(Args[ArgIdx])) {
1096 return TemplateDeductionResult::MiscellaneousDeductionFailure;
1100 S, TemplateParams, Params[
ParamIdx].getUnqualifiedType(),
1101 Args[ArgIdx].getUnqualifiedType(), Info, Deduced, TDF,
1104 Result != TemplateDeductionResult::Success)
1119 PackDeductionScope PackScope(S, TemplateParams, Deduced, Info, Pattern);
1123 if (
ParamIdx + 1 == NumParams || PackScope.hasFixedArity()) {
1124 for (; ArgIdx < NumArgs && PackScope.hasNextElement(); ++ArgIdx) {
1130 Result != TemplateDeductionResult::Success)
1133 PackScope.nextPackElement();
1154 if (NumExpansions && !PackScope.isPartiallyExpanded()) {
1155 for (
unsigned I = 0; I != *NumExpansions && ArgIdx < NumArgs;
1157 PackScope.nextPackElement();
1163 if (
auto Result = PackScope.finish();
1164 Result != TemplateDeductionResult::Success)
1175 isa<PackExpansionType>(Args[ArgIdx]))
1176 return TemplateDeductionResult::Success;
1179 if (ArgIdx < NumArgs)
1180 return TemplateDeductionResult::MiscellaneousDeductionFailure;
1182 return TemplateDeductionResult::Success;
1194 if (ParamQs == ArgQs)
1247 if (!Guide || !Guide->isImplicit())
1249 return Guide->getDeducedTemplate()->getTemplateParameters()->size();
1259 if (ParamRef->getPointeeType().getQualifiers())
1262 return TypeParm && TypeParm->
getIndex() >= FirstInnerIndex;
1268 return cast<CXXRecordDecl>(
1325 assert(
T->
isRecordType() &&
"Base class that isn't a record?");
1327 ToVisit.push_back(
T);
1336 while (!ToVisit.empty()) {
1337 QualType NextT = ToVisit.pop_back_val();
1343 S, TemplateParams,
P, NextT, BaseInfo, DeducedCopy);
1349 Matches.insert({RD, DeducedCopy});
1360 if (Matches.size() > 1) {
1362 for (
const auto &Match : Matches)
1363 AddBases(Match.first);
1367 while (Matches.size() > 1 && !ToVisit.empty()) {
1377 if (Matches.empty())
1379 if (Matches.size() > 1)
1382 std::swap(Matches.front().second, Deduced);
1418 if (
const auto *AExp = dyn_cast<PackExpansionType>(A))
1419 A = AExp->getPattern();
1500 TDF &= ~TDF_TopLevelParameterTypeList;
1503 P =
P->getPointeeType();
1520 unsigned Index = TTP->getIndex();
1535 Info.
Param = cast<TemplateTypeParmDecl>(TemplateParams->
getParam(Index));
1547 "saw template type parameter with wrong depth");
1549 "Unresolved overloaded function");
1569 Info.
Param = cast<TemplateTypeParmDecl>(TemplateParams->
getParam(Index));
1589 Info.
Param = cast<TemplateTypeParmDecl>(TemplateParams->
getParam(Index));
1634 if (!
P->isDependentType()) {
1650 switch (
P.getCanonicalType()->getTypeClass()) {
1652#define NON_CANONICAL_TYPE(Class, Base) \
1653 case Type::Class: llvm_unreachable("deducing non-canonical type: " #Class);
1654#define TYPE(Class, Base)
1655#include "clang/AST/TypeNodes.inc"
1657 case Type::TemplateTypeParm:
1658 case Type::SubstTemplateTypeParmPack:
1659 llvm_unreachable(
"Type nodes handled above");
1667 if (
P->isDependentType())
1671 case Type::VariableArray:
1673 case Type::FunctionNoProto:
1676 case Type::ObjCObject:
1677 case Type::ObjCInterface:
1678 case Type::ObjCObjectPointer:
1688 case Type::Complex: {
1693 S, TemplateParams, CP->getElementType(), CA->getElementType(), Info,
1698 case Type::Atomic: {
1703 S, TemplateParams, PA->getValueType(), AA->getValueType(), Info,
1708 case Type::Pointer: {
1719 PointeeType, Info, Deduced,
1724 case Type::LValueReference: {
1731 S, TemplateParams, RP->getPointeeType(), RA->getPointeeType(), Info,
1736 case Type::RValueReference: {
1743 S, TemplateParams, RP->getPointeeType(), RA->getPointeeType(), Info,
1748 case Type::IncompleteArray: {
1754 assert(IAP &&
"Template parameter not of incomplete array type");
1757 S, TemplateParams, IAP->getElementType(), IAA->getElementType(), Info,
1762 case Type::ConstantArray: {
1766 if (!CAA || CAA->getSize() != CAP->getSize())
1770 S, TemplateParams, CAP->getElementType(), CAA->getElementType(), Info,
1775 case Type::DependentSizedArray: {
1784 S, TemplateParams, DAP->getElementType(), AA->getElementType(),
1798 "saw non-type template parameter with wrong depth");
1799 if (
const auto *CAA = dyn_cast<ConstantArrayType>(AA)) {
1800 llvm::APSInt Size(CAA->getSize());
1803 true, Info, Deduced);
1805 if (
const auto *DAA = dyn_cast<DependentSizedArrayType>(AA))
1806 if (DAA->getSizeExpr())
1808 S, TemplateParams, NTTP, DAA->getSizeExpr(), Info, Deduced);
1817 case Type::FunctionProto: {
1823 if (FPP->getMethodQuals() != FPA->getMethodQuals() ||
1824 FPP->getRefQualifier() != FPA->getRefQualifier() ||
1825 FPP->isVariadic() != FPA->isVariadic())
1830 S, TemplateParams, FPP->getReturnType(), FPA->getReturnType(),
1839 S, TemplateParams, FPP->param_type_begin(), FPP->getNumParams(),
1840 FPA->param_type_begin(), FPA->getNumParams(), Info, Deduced,
1851 Expr *NoexceptExpr = FPP->getNoexceptExpr();
1856 "saw non-type template parameter with wrong depth");
1858 llvm::APSInt Noexcept(1);
1859 switch (FPA->canThrow()) {
1869 true, Info, Deduced);
1872 if (
Expr *ArgNoexceptExpr = FPA->getNoexceptExpr())
1874 S, TemplateParams, NTTP, ArgNoexceptExpr, Info, Deduced);
1887 case Type::InjectedClassName:
1896 case Type::TemplateSpecialization: {
1921 Deduced = DeducedOrig;
1925 TemplateParams,
P, Info, Deduced);
1939 case Type::MemberPointer: {
1956 S, TemplateParams, PPT, APT, Info, Deduced, SubTDF);
1960 S, TemplateParams,
QualType(MPP->getClass(), 0),
1961 QualType(MPA->getClass(), 0), Info, Deduced, SubTDF);
1969 case Type::BlockPointer: {
1975 S, TemplateParams, BPP->getPointeeType(), BPA->getPointeeType(), Info,
1982 case Type::ExtVector: {
1987 if (VP->getNumElements() != VA->getNumElements())
1989 ElementType = VA->getElementType();
1994 ElementType = VA->getElementType();
2000 S, TemplateParams, VP->getElementType(), ElementType, Info, Deduced,
2004 case Type::DependentVector: {
2010 S, TemplateParams, VP->getElementType(), VA->getElementType(),
2011 Info, Deduced, TDF);
2022 ArgSize = VA->getNumElements();
2034 S, TemplateParams, VP->getElementType(), VA->getElementType(),
2035 Info, Deduced, TDF);
2046 VA->getSizeExpr(), Info, Deduced);
2055 case Type::DependentSizedExtVector: {
2061 S, TemplateParams, VP->getElementType(), VA->getElementType(),
2062 Info, Deduced, TDF);
2073 ArgSize = VA->getNumElements();
2085 S, TemplateParams, VP->getElementType(), VA->getElementType(),
2086 Info, Deduced, TDF);
2097 VA->getSizeExpr(), Info, Deduced);
2107 case Type::ConstantMatrix: {
2114 if (MP->getNumRows() != MA->getNumRows() ||
2115 MP->getNumColumns() != MA->getNumColumns()) {
2120 S, TemplateParams, MP->getElementType(), MA->getElementType(), Info,
2124 case Type::DependentSizedMatrix: {
2133 Info, Deduced, TDF);
2138 auto DeduceMatrixArg =
2139 [&S, &Info, &Deduced, &TemplateParams](
2143 const auto *ACM = dyn_cast<ConstantMatrixType>(A);
2144 const auto *ADM = dyn_cast<DependentSizedMatrixType>(A);
2145 if (!ParamExpr->isValueDependent()) {
2146 std::optional<llvm::APSInt> ParamConst =
2147 ParamExpr->getIntegerConstantExpr(S.
Context);
2152 if ((ACM->*GetArgDimension)() == *ParamConst)
2157 Expr *ArgExpr = (ADM->*GetArgDimensionExpr)();
2158 if (std::optional<llvm::APSInt> ArgConst =
2160 if (*ArgConst == *ParamConst)
2171 llvm::APSInt ArgConst(
2173 ArgConst = (ACM->*GetArgDimension)();
2176 true, Info, Deduced);
2180 (ADM->*GetArgDimensionExpr)(),
2184 if (
auto Result = DeduceMatrixArg(MP->getRowExpr(), MA,
2190 return DeduceMatrixArg(MP->getColumnExpr(), MA,
2198 case Type::DependentAddressSpace: {
2204 S, TemplateParams, ASP->getPointeeType(), ASA->getPointeeType(),
2205 Info, Deduced, TDF);
2216 S, TemplateParams, NTTP, ASA->getAddrSpaceExpr(), Info, Deduced);
2226 S, TemplateParams, ASP->getPointeeType(),
2239 true, Info, Deduced);
2244 case Type::DependentBitInt: {
2248 if (IP->isUnsigned() != IA->isUnsigned())
2257 ArgSize = IA->getNumBits();
2265 if (IP->isUnsigned() != IA->isUnsigned())
2273 case Type::TypeOfExpr:
2275 case Type::DependentName:
2276 case Type::UnresolvedUsing:
2277 case Type::Decltype:
2278 case Type::UnaryTransform:
2279 case Type::DeducedTemplateSpecialization:
2280 case Type::DependentTemplateSpecialization:
2281 case Type::PackExpansion:
2283 case Type::ArrayParameter:
2287 case Type::PackIndexing: {
2297 llvm_unreachable(
"Invalid Type Class!");
2311 switch (
P.getKind()) {
2313 llvm_unreachable(
"Null template argument in parameter list");
2318 S, TemplateParams,
P.getAsType(), A.
getAsType(), Info, Deduced, 0);
2332 llvm_unreachable(
"caller should handle pack expansions");
2399 llvm_unreachable(
"Unknown template argument kind");
2405 llvm_unreachable(
"Argument packs should be expanded by the caller!");
2408 llvm_unreachable(
"Invalid TemplateArgument Kind!");
2421 if (ArgIdx == Args.size())
2428 assert(ArgIdx == Args.size() - 1 &&
"Pack not at the end of argument list?");
2431 return ArgIdx < Args.size();
2437 bool FoundPackExpansion =
false;
2438 for (
const auto &A : Args) {
2439 if (FoundPackExpansion)
2447 if (A.isPackExpansion())
2448 FoundPackExpansion =
true;
2460 bool NumberOfArgumentsMustMatch) {
2475 if (!
P.isPackExpansion()) {
2480 return NumberOfArgumentsMustMatch
2487 if (As[ArgIdx].isPackExpansion())
2492 As[ArgIdx], Info, Deduced);
2511 PackDeductionScope PackScope(S, TemplateParams, Deduced, Info, Pattern);
2517 PackScope.hasNextElement();
2521 As[ArgIdx], Info, Deduced);
2525 PackScope.nextPackElement();
2530 if (
auto Result = PackScope.finish();
2542 bool NumberOfArgumentsMustMatch) {
2543 return ::DeduceTemplateArguments(*
this, TemplateParams, Ps, As, Info, Deduced,
2544 NumberOfArgumentsMustMatch);
2552 bool PackExpansionMatchesPack =
false) {
2555 if (PackExpansionMatchesPack &&
X.isPackExpansion() && !Y.
isPackExpansion())
2556 X =
X.getPackExpansionPattern();
2561 switch (
X.getKind()) {
2563 llvm_unreachable(
"Comparing NULL template argument");
2586 return X.structurallyEquals(Y);
2589 llvm::FoldingSetNodeID XID, YID;
2590 X.getAsExpr()->Profile(XID, Context,
true);
2596 unsigned PackIterationSize =
X.pack_size();
2605 bool XHasMoreArg =
X.pack_size() > Y.
pack_size();
2606 if (!(XHasMoreArg &&
X.pack_elements().back().isPackExpansion()) &&
2607 !(!XHasMoreArg && Y.
pack_elements().back().isPackExpansion()))
2616 for (
unsigned i = 0; i < PackIterationSize; ++i)
2618 PackExpansionMatchesPack))
2624 llvm_unreachable(
"Invalid TemplateArgument Kind!");
2645 llvm_unreachable(
"Can't get a NULL template argument here");
2679 Builder.MakeTrivial(
Context, DTN->getQualifier(), Loc);
2682 Builder.MakeTrivial(
Context, QTN->getQualifier(), Loc);
2686 Builder.getWithLocInContext(
Context), Loc);
2699 llvm_unreachable(
"Invalid TemplateArgument Kind!");
2717 unsigned ArgumentPackIndex) {
2739 CanonicalPackedArgsBuilder;
2747 "deduced nested pack");
2754 diag::err_template_arg_deduced_incomplete_pack)
2758 if (ConvertArg(InnerArg, SugaredPackedArgsBuilder.size()))
2762 SugaredPackedArgsBuilder.push_back(SugaredOutput.pop_back_val());
2763 CanonicalPackedArgsBuilder.push_back(CanonicalOutput.pop_back_val());
2768 if (SugaredPackedArgsBuilder.empty()) {
2773 if (
auto *NTTP = dyn_cast<NonTypeTemplateParmDecl>(Param)) {
2775 NTTP, SugaredOutput,
2778 S.
SubstType(NTTP->getType(), Args, NTTP->getLocation(),
2779 NTTP->getDeclName()).isNull())
2781 }
else if (
auto *TTP = dyn_cast<TemplateTemplateParmDecl>(Param)) {
2792 SugaredOutput.push_back(
2795 S.
Context, CanonicalPackedArgsBuilder));
2799 return ConvertArg(Arg, 0);
2805template <
typename TemplateDeclT>
2807 Sema &S, TemplateDeclT *Template,
bool IsDeduced,
2813 unsigned NumAlreadyConverted = 0,
bool PartialOverloading =
false) {
2816 for (
unsigned I = 0, N = TemplateParams->
size(); I != N; ++I) {
2825 PackDeductionScope(S, TemplateParams, Deduced, Info, I).finish();
2830 if (!Deduced[I].isNull()) {
2831 if (I < NumAlreadyConverted) {
2836 CurrentInstantiationScope->getPartiallySubstitutedPack() == Param) {
2839 CurrentInstantiationScope->ResetPartiallySubstitutedPack();
2846 SugaredBuilder.push_back(Deduced[I]);
2847 CanonicalBuilder.push_back(
2856 IsDeduced, SugaredBuilder,
2857 CanonicalBuilder)) {
2870 bool HasDefaultArg =
false;
2873 assert(isa<ClassTemplatePartialSpecializationDecl>(Template) ||
2874 isa<VarTemplatePartialSpecializationDecl>(Template));
2883 if (Rec->isLambda())
2884 if (
auto *Method = dyn_cast<CXXMethodDecl>(Rec->getDeclContext())) {
2886 ThisTypeQuals = Method->getMethodQualifiers();
2894 SugaredBuilder, CanonicalBuilder, HasDefaultArg);
2903 if (PartialOverloading)
break;
2928 if (
auto *DC = dyn_cast<DeclContext>(D))
2934 static constexpr bool value =
false;
2938 static constexpr bool value =
true;
2942 static constexpr bool value =
true;
2944template <
typename TemplateDeclT>
2959template <
typename TemplateDeclT>
2966 Template->getAssociatedConstraints(AssociatedConstraints);
2968 std::optional<ArrayRef<TemplateArgument>> Innermost;
2972 Innermost = CanonicalDeducedArgs;
2975 Template, Template->getDeclContext(),
false, Innermost,
2999template <
typename T>
3000static std::enable_if_t<IsPartialSpecialization<T>::value,
3003 Sema &S,
T *Partial,
bool IsPartialOrdering,
3019 S, Partial, IsPartialOrdering, Deduced, Info, SugaredBuilder,
3030 Info.
reset(SugaredDeducedArgumentList, CanonicalDeducedArgumentList);
3038 auto *Template = Partial->getSpecializedTemplate();
3040 Partial->getTemplateArgsAsWritten();
3051 if (
ParamIdx >= Partial->getTemplateParameters()->size())
3052 ParamIdx = Partial->getTemplateParameters()->size() - 1;
3055 Partial->getTemplateParameters()->getParam(
ParamIdx));
3057 Info.
FirstArg = (*PartialTemplArgInfo)[ArgIdx].getArgument();
3063 CanonicalConvertedInstArgs;
3065 Template, Partial->getLocation(), InstArgs,
false,
3066 SugaredConvertedInstArgs, CanonicalConvertedInstArgs,
3073 for (
unsigned I = 0, E = TemplateParams->
size(); I != E; ++I) {
3076 IsPartialOrdering)) {
3088 CanonicalBuilder, Info);
3116 SugaredBuilder, CanonicalBuilder,
3124 for (
unsigned I = 0, E = TemplateParams->
size(); I != E; ++I) {
3139 CanonicalBuilder, Info);
3149template <
typename T>
3150static std::enable_if_t<IsPartialSpecialization<T>::value,
3155 if (Partial->isInvalidDecl())
3174 Deduced.resize(Partial->getTemplateParameters()->size());
3176 S, Partial->getTemplateParameters(),
3177 Partial->getTemplateArgs().asArray(), TemplateArgs, Info, Deduced,
3193 Result = ::FinishTemplateArgumentDeduction(S, Partial,
3195 TemplateArgs, Deduced, Info);
3204 return ::DeduceTemplateArguments(*
this, Partial, TemplateArgs, Info);
3210 return ::DeduceTemplateArguments(*
this, Partial, TemplateArgs, Info);
3217 return Spec->getTemplateName().getAsTemplateDecl() !=
nullptr;
3267 if (ExplicitTemplateArgs.
size() == 0) {
3271 ParamTypes.push_back(
P->getType());
3301 ExplicitTemplateArgs,
true, SugaredBuilder,
3305 unsigned Index = SugaredBuilder.size();
3306 if (Index >= TemplateParams->
size())
3319 CanonicalExplicitArgumentList);
3331 unsigned PartiallySubstitutedPackIndex = -1u;
3332 if (!CanonicalBuilder.empty()) {
3335 auto *Param = TemplateParams->
getParam(CanonicalBuilder.size() - 1);
3339 if (!Expansions || Arg.
pack_size() < *Expansions) {
3340 PartiallySubstitutedPackIndex = CanonicalBuilder.size() - 1;
3349 assert(Proto &&
"Function template does not have a prototype?");
3357 SugaredExplicitArgumentList->
asArray(),
3367 nullptr, ExtParamInfos))
3384 ThisTypeQuals = Method->getMethodQualifiers();
3398 Diag(
Function->getLocation(), diag::err_kern_type_not_void_return)
3409 nullptr, ExtParamInfos))
3422 Function->getLocation(), EPI.ExceptionSpec, ExceptionStorage,
3425 SugaredExplicitArgumentList->
asArray(),
3450 Deduced.reserve(TemplateParams->
size());
3451 for (
unsigned I = 0, N = SugaredExplicitArgumentList->
size(); I != N; ++I) {
3453 if (I == PartiallySubstitutedPackIndex)
3456 Deduced.push_back(Arg);
3525 if (AQuals == DeducedAQuals) {
3543 bool ObjCLifetimeConversion =
false;
3547 ObjCLifetimeConversion) ||
3593 if (PD->isParameterPack()) {
3594 unsigned NumExpansions =
3596 if (Idx + NumExpansions >
ParamIdx)
3598 Idx += NumExpansions;
3606 llvm_unreachable(
"parameter index would not be produced from template");
3618 return isa<CXXConstructorDecl>(D)
3619 ? cast<CXXConstructorDecl>(D)->getExplicitSpecifier()
3620 : cast<CXXConversionDecl>(D)->getExplicitSpecifier();
3623 isa<CXXConstructorDecl>(D)
3624 ? cast<CXXConstructorDecl>(D)->setExplicitSpecifier(ES)
3625 : cast<CXXConversionDecl>(D)->setExplicitSpecifier(ES);
3636 S, Info.
getLocation(), FunctionTemplate, DeducedArgs,
3663 bool PartialOverloading, llvm::function_ref<
bool()> CheckNonDependent) {
3687 NumExplicitlySpecified, PartialOverloading);
3700 if (CheckNonDependent())
3708 Info.
reset(SugaredDeducedArgumentList, CanonicalDeducedArgumentList);
3740 assert(
Specialization->getPrimaryTemplate()->getCanonicalDecl() ==
3746 CanonicalDeducedArgumentList &&
3766 if (!PartialOverloading ||
3767 (CanonicalBuilder.size() ==
3784 if (isa<CXXConstructorDecl, CXXConversionDecl>(
Specialization)) {
3793 if (OriginalCallArgs) {
3798 llvm::SmallDenseMap<std::pair<unsigned, QualType>,
QualType> DeducedATypes;
3799 for (
unsigned I = 0, N = OriginalCallArgs->size(); I != N; ++I) {
3803 unsigned ExplicitOffset =
3823 if (CacheEntry.
isNull()) {
3832 DeducedA = CacheEntry;
3847 SuppressedDiagnosticsMap::iterator
3867 if (Method->isImplicitObjectMemberFunction()) {
3888 bool ParamWasReference,
3897 if (ParamWasReference)
3914 nullptr, FailedTSC))
3955 if (ArgType.
isNull())
continue;
3975 Deduced(TemplateParams->
size());
3978 S, TemplateParams, ParamType, ArgType, Info, Deduced, TDF);
4016 assert(Arg &&
"expected a non-null arg expression");
4018 ParamRefType !=
nullptr, FailedTSC);
4026 assert(Arg &&
"expected a non-null arg expression");
4081 (isa<PointerType>(ParamType) &&
4100 bool DecomposedParam,
unsigned ArgIdx,
unsigned TDF,
4125 ElTy = ArrTy->getElementType();
4135 if (isa<DesignatedInitExpr>(E))
4142 S, TemplateParams, 0, ElTy, E->getType(),
4144 OriginalCallArgs,
true, ArgIdx, TDF);
4152 if (
auto *DependentArrTy = dyn_cast_or_null<DependentSizedArrayType>(ArrTy)) {
4163 S, TemplateParams, NTTP, llvm::APSInt(Size),
T,
4164 true, Info, Deduced);
4182 bool DecomposedParam,
unsigned ArgIdx,
unsigned TDF,
4185 QualType OrigParamType = ParamType;
4190 S, TemplateParams, FirstInnerIndex, ParamType, ArgType,
4191 ArgClassification, Arg, TDF, FailedTSC))
4195 if (
InitListExpr *ILE = dyn_cast_if_present<InitListExpr>(Arg))
4197 Deduced, OriginalCallArgs, ArgIdx, TDF);
4205 OriginalCallArgs.push_back(
4208 ArgType, Info, Deduced, TDF);
4240 bool PartialOverloading,
bool AggregateDeductionCandidate,
4247 unsigned NumParams =
Function->getNumParams();
4248 bool HasExplicitObject =
false;
4249 int ExplicitObjectOffset = 0;
4250 if (
Function->hasCXXExplicitFunctionObjectParameter()) {
4251 HasExplicitObject =
true;
4252 ExplicitObjectOffset = 1;
4261 if (Args.size() <
Function->getMinRequiredExplicitArguments() &&
4262 !PartialOverloading)
4265 PartialOverloading)) {
4267 if (Proto->isTemplateVariadic())
4269 else if (!Proto->isVariadic())
4280 unsigned NumExplicitlySpecified = 0;
4281 if (ExplicitTemplateArgs) {
4284 Result = SubstituteExplicitTemplateArguments(
4285 FunctionTemplate, *ExplicitTemplateArgs, Deduced, ParamTypes, nullptr,
4291 NumExplicitlySpecified = Deduced.size();
4294 for (
unsigned I = 0; I != NumParams; ++I)
4295 ParamTypes.push_back(
Function->getParamDecl(I)->getType());
4301 auto DeduceCallArgument = [&](
QualType ParamType,
unsigned ArgIdx,
4302 bool ExplicitObjetArgument) {
4310 if (ExplicitObjetArgument) {
4313 *
this, TemplateParams, FirstInnerIndex, ParamType, ObjectType,
4314 ObjectClassification,
4315 nullptr, Info, Deduced, OriginalCallArgs,
4321 *
this, TemplateParams, FirstInnerIndex, ParamType,
4322 Args[ArgIdx]->getType(), Args[ArgIdx]->Classify(
getASTContext()),
4323 Args[ArgIdx], Info, Deduced, OriginalCallArgs,
false,
4328 Deduced.resize(TemplateParams->
size());
4330 for (
unsigned ParamIdx = 0, NumParamTypes = ParamTypes.size(), ArgIdx = 0;
4335 dyn_cast<PackExpansionType>(ParamType);
4336 if (!ParamExpansion) {
4338 if (ArgIdx >= Args.size() && !(HasExplicitObject &&
ParamIdx == 0))
4341 ParamTypesForArgChecking.push_back(ParamType);
4343 if (
ParamIdx == 0 && HasExplicitObject) {
4344 if (
auto Result = DeduceCallArgument(ParamType, 0,
4351 if (
auto Result = DeduceCallArgument(ParamType, ArgIdx++,
4359 bool IsTrailingPack =
ParamIdx + 1 == NumParamTypes;
4362 PackDeductionScope PackScope(*
this, TemplateParams, Deduced, Info,
4364 AggregateDeductionCandidate && IsTrailingPack);
4382 if (IsTrailingPack || PackScope.hasFixedArity()) {
4383 for (; ArgIdx < Args.size() && PackScope.hasNextElement();
4384 PackScope.nextPackElement(), ++ArgIdx) {
4385 ParamTypesForArgChecking.push_back(ParamPattern);
4386 if (
auto Result = DeduceCallArgument(ParamPattern, ArgIdx,
4395 std::optional<unsigned> NumExpansions =
4397 if (NumExpansions && !PackScope.isPartiallyExpanded()) {
4398 for (
unsigned I = 0; I != *NumExpansions && ArgIdx < Args.size();
4400 ParamTypesForArgChecking.push_back(ParamPattern);
4403 PackScope.nextPackElement();
4405 }
else if (!IsTrailingPack && !PackScope.isPartiallyExpanded() &&
4406 PackScope.isDeducedFromEarlierParameter()) {
4419 std::optional<unsigned> ArgPosAfterSubstitution =
4420 PackScope.getSavedPackSizeIfAllEqual();
4421 if (!ArgPosAfterSubstitution)
4424 unsigned PackArgEnd = ArgIdx + *ArgPosAfterSubstitution;
4425 for (; ArgIdx < PackArgEnd && ArgIdx < Args.size(); ArgIdx++) {
4426 ParamTypesForArgChecking.push_back(ParamPattern);
4427 if (
auto Result = DeduceCallArgument(ParamPattern, ArgIdx,
4432 PackScope.nextPackElement();
4439 if (
auto Result = PackScope.finish();
4450 Result = FinishTemplateArgumentDeduction(
4451 FunctionTemplate, Deduced, NumExplicitlySpecified, Specialization, Info,
4452 &OriginalCallArgs, PartialOverloading, [&, CallingCtx]() {
4453 ContextRAII SavedContext(*this, CallingCtx);
4454 return CheckNonDependent(ParamTypesForArgChecking);
4462 bool AdjustExceptionSpec) {
4463 if (ArgFunctionType.
isNull())
4464 return ArgFunctionType;
4469 bool Rebuild =
false;
4472 if (EPI.ExtInfo.getCC() != CC) {
4473 EPI.
ExtInfo = EPI.ExtInfo.withCallingConv(CC);
4477 bool NoReturn = FunctionTypeP->getNoReturnAttr();
4478 if (EPI.ExtInfo.getNoReturn() != NoReturn) {
4479 EPI.ExtInfo = EPI.ExtInfo.withNoReturn(NoReturn);
4483 if (AdjustExceptionSpec && (FunctionTypeP->hasExceptionSpec() ||
4485 EPI.ExceptionSpec = FunctionTypeP->getExtProtoInfo().ExceptionSpec;
4490 return ArgFunctionType;
4528 bool IsAddressOfFunction) {
4540 unsigned NumExplicitlySpecified = 0;
4542 if (ExplicitTemplateArgs) {
4545 Result = SubstituteExplicitTemplateArguments(
4546 FunctionTemplate, *ExplicitTemplateArgs, Deduced, ParamTypes,
4547 &FunctionType, Info);
4552 NumExplicitlySpecified = Deduced.size();
4558 if (!IsAddressOfFunction)
4567 Deduced.resize(TemplateParams->
size());
4571 bool HasDeducedReturnType =
false;
4573 Function->getReturnType()->getContainedAutoType()) {
4575 HasDeducedReturnType =
true;
4583 *
this, TemplateParams,
FunctionType, ArgFunctionType, Info, Deduced,
4591 Result = FinishTemplateArgumentDeduction(FunctionTemplate, Deduced,
4592 NumExplicitlySpecified,
4593 Specialization, Info);
4600 if (HasDeducedReturnType && IsAddressOfFunction &&
4611 auto *SpecializationFPT =
4613 if (IsAddressOfFunction &&
getLangOpts().CPlusPlus17 &&
4623 if (!IsAddressOfFunction) {
4629 if (HasDeducedReturnType) {
4638 if (!ArgFunctionType.
isNull()) {
4643 SpecializationType, ArgFunctionType)) {
4676 P = PRef->getPointeeType();
4688 P =
P.getUnqualifiedType();
4695 assert(!A->
isReferenceType() &&
"Reference types were handled above");
4700 if (
P->isArrayType())
4705 else if (
P->isFunctionType())
4710 P =
P.getUnqualifiedType();
4732 Deduced.resize(TemplateParams->
size());
4761 ParamType, ObjectType, ObjectClassification,
4762 nullptr, Info, Deduced, OriginalCallArgs,
4769 *
this, TemplateParams,
P, A, Info, Deduced, TDF);
4779 Result = FinishTemplateArgumentDeduction(ConversionTemplate, Deduced, 0,
4780 ConversionSpecialized, Info,
4783 Specialization = cast_or_null<CXXConversionDecl>(ConversionSpecialized);
4816 bool IsAddressOfFunction) {
4819 IsAddressOfFunction);
4823 struct DependentAuto {
bool IsPack; };
4827 class SubstituteDeducedTypeTransform :
4830 bool ReplacementIsPack;
4835 SubstituteDeducedTypeTransform(
Sema &SemaRef, DependentAuto DA)
4837 ReplacementIsPack(DA.IsPack), UseTypeSugar(
true) {}
4839 SubstituteDeducedTypeTransform(
Sema &SemaRef,
QualType Replacement,
4840 bool UseTypeSugar =
true)
4842 Replacement(Replacement), ReplacementIsPack(
false),
4843 UseTypeSugar(UseTypeSugar) {}
4846 assert(isa<TemplateTypeParmType>(Replacement) &&
4847 "unexpected unsugared replacement kind");
4865 return TransformDesugared(TLB, TL);
4867 QualType Result = SemaRef.Context.getAutoType(
4876 QualType TransformDeducedTemplateSpecializationType(
4879 return TransformDesugared(TLB, TL);
4881 QualType Result = SemaRef.Context.getDeducedTemplateSpecializationType(
4883 Replacement, Replacement.isNull());
4901 return inherited::TransformExceptionSpec(Loc, ESI, Exceptions, Changed);
4909 return TransformType(TLB, TL);
4925 Deduced,
TypeLoc.getNameLoc())));
4926 for (
unsigned I = 0,
C =
TypeLoc.getNumArgs(); I !=
C; ++I)
4932 SugaredConverted, CanonicalConverted))
4942 llvm::raw_string_ostream OS(Buf);
4943 OS <<
"'" << Concept->getName();
4944 if (
TypeLoc.hasExplicitTemplateArgs()) {
4947 Type.getTypeConstraintConcept()->getTemplateParameters());
4952 diag::err_placeholder_constraints_not_satisfied)
4981 bool IgnoreConstraints,
4984 if (
Init->containsErrors())
4997 DependentAuto DependentResult = {
5000 if (!DependentDeduction &&
5002 Init->containsUnexpandedParameterPack())) {
5003 Result = SubstituteDeducedTypeTransform(*
this, DependentResult).Apply(
Type);
5004 assert(!
Result.isNull() &&
"substituting DependentTy can't fail");
5009 auto *String = dyn_cast<StringLiteral>(
Init);
5011 Diag(
Type.getBeginLoc(), diag::ext_c23_auto_non_plain_identifier);
5013 Result = SubstituteDeducedTypeTransform(*
this, DependentResult).Apply(TL);
5014 assert(!
Result.isNull() &&
"substituting DependentTy can't fail");
5020 Diag(
Type.getBeginLoc(), diag::ext_c23_auto_non_plain_identifier);
5023 auto *InitList = dyn_cast<InitListExpr>(
Init);
5025 Diag(
Init->getBeginLoc(), diag::err_auto_init_list_from_c)
5037 if (
Init->isTypeDependent()) {
5039 SubstituteDeducedTypeTransform(*
this, DependentResult).Apply(
Type);
5040 assert(!
Result.isNull() &&
"substituting DependentTy can't fail");
5052 Diag(
Init->getBeginLoc(), diag::err_decltype_auto_initializer_list);
5065 nullptr,
false,
false,
false);
5069 Context, Loc, Loc, TemplParamPtr, Loc,
nullptr);
5079 for (
Expr *
Init : InitList->inits()) {
5082 if (isa<DesignatedInitExpr>(
Init))
5085 *
this, TemplateParamsSt.get(), 0, TemplArg,
Init->getType(),
5087 OriginalCallArgs,
true,
5093 <<
Init->getSourceRange();
5096 return DeductionFailed(TDK);
5101 DeducedFromInitRange =
Init->getSourceRange();
5105 Diag(Loc, diag::err_auto_bitfield);
5109 SubstituteDeducedTypeTransform(*
this, TemplArg).Apply(
Type);
5110 assert(!FuncParam.
isNull() &&
5111 "substituting template parameter for 'auto' failed");
5113 *
this, TemplateParamsSt.get(), 0, FuncParam,
Init->getType(),
5115 OriginalCallArgs,
false, 0, 0,
5118 return DeductionFailed(TDK);
5155 assert((
bool)InitList == OriginalArg.DecomposedParam &&
5156 "decomposed non-init-list in auto deduction?");
5161 return DeductionFailed(TDK);
5171 return SubstituteDeducedTypeTransform(*
this, TypeToReplaceAuto)
5172 .TransformType(TypeWithAuto);
5178 return SubstituteDeducedTypeTransform(*
this, TypeToReplaceAuto)
5179 .TransformType(TypeWithAuto);
5183 return SubstituteDeducedTypeTransform(*
this, DependentAuto{
false})
5184 .TransformType(TypeWithAuto);
5189 return SubstituteDeducedTypeTransform(*
this, DependentAuto{
false})
5190 .TransformType(TypeWithAuto);
5195 return SubstituteDeducedTypeTransform(*
this, TypeToReplaceAuto,
5197 .TransformType(TypeWithAuto);
5202 return SubstituteDeducedTypeTransform(*
this, TypeToReplaceAuto,
5204 .TransformType(TypeWithAuto);
5208 if (isa<InitListExpr>(
Init))
5211 ? diag::err_init_capture_deduction_failure_from_init_list
5212 : diag::err_auto_var_deduction_failure_from_init_list)
5216 VDecl->
isInitCapture() ? diag::err_init_capture_deduction_failure
5217 : diag::err_auto_var_deduction_failure)
5219 <<
Init->getSourceRange();
5251 "failed to deduce lambda return type");
5278 Diag(Loc, diag::err_auto_fn_used_before_defined) << FD;
5282 return StillUndeduced;
5326 "expected a member function with no explicit object parameter");
5351 assert(Proto1 && Proto2 &&
"Function templates must have prototypes");
5354 Deduced.resize(TemplateParams->
size());
5363 Args1.data(), Args1.size(), Info, Deduced,
5374 S, TemplateParams, Proto2->getReturnType(), Proto1->
getReturnType(),
5384 S, TemplateParams, FD2->
getType(), FD1->
getType(), Info, Deduced,
5397 unsigned ArgIdx = 0, NumArgs = Deduced.size();
5398 for (; ArgIdx != NumArgs; ++ArgIdx)
5399 if (Deduced[ArgIdx].isNull())
5406 if (ArgIdx == NumArgs) {
5413 llvm::SmallBitVector UsedParameters(TemplateParams->
size());
5416 for (
unsigned I = 0, N = Args2.size(); I != N; ++I)
5424 TemplateParams->
getDepth(), UsedParameters);
5434 for (; ArgIdx != NumArgs; ++ArgIdx)
5437 if (Deduced[ArgIdx].isNull() && UsedParameters[ArgIdx])
5478 bool ShouldConvert1 =
false;
5479 bool ShouldConvert2 =
false;
5490 const CXXMethodDecl *Method1 = dyn_cast<CXXMethodDecl>(FD1);
5491 const CXXMethodDecl *Method2 = dyn_cast<CXXMethodDecl>(FD2);
5501 ShouldConvert1 = Method1 && !Method1->isExplicitObjectMemberFunction();
5503 if (ShouldConvert1) {
5507 : Proto2->param_type_begin()[0]->isRValueReferenceType();
5511 Args1.push_back(Obj1Ty);
5513 if (ShouldConvert2) {
5516 ? Method1->getRefQualifier() ==
RQ_RValue
5521 Args2.push_back(Obj2Ty);
5523 size_t NumComparedArguments = NumCallArguments1 + ShouldConvert1;
5527 Args2.insert(Args2.end(), Proto2->param_type_begin(),
5528 Proto2->param_type_end());
5533 Args1.resize(std::min(Args1.size(), NumComparedArguments));
5534 Args2.resize(std::min(Args2.size(), NumComparedArguments));
5537 std::reverse(Args2.begin(), Args2.end());
5546 if (Better1 != Better2)
5547 return Better1 ? FT1 : FT2;
5549 if (!Better1 && !Better2)
5558 Param1.reserve(FD1->
param_size() + ShouldConvert1);
5560 Param1.push_back(Obj1Ty);
5562 Param1.push_back(
P->getType());
5565 Param2.reserve(FD2->
param_size() + ShouldConvert2);
5567 Param2.push_back(Obj2Ty);
5569 Param2.push_back(
P->getType());
5571 unsigned NumParams1 = Param1.size();
5572 unsigned NumParams2 = Param2.size();
5578 if (Variadic1 != Variadic2) {
5579 if (Variadic1 && NumParams1 > NumParams2)
5581 if (Variadic2 && NumParams2 > NumParams1)
5587 for (
int i = 0, e = std::min(NumParams1, NumParams2); i < e; ++i) {
5588 QualType T1 = Param1[i].getCanonicalType();
5589 QualType T2 = Param2[i].getCanonicalType();
5590 auto *TST1 = dyn_cast<TemplateSpecializationType>(T1);
5591 auto *TST2 = dyn_cast<TemplateSpecializationType>(T2);
5596 assert(TST1->template_arguments().size() ==
5597 TST2->template_arguments().size());
5602 bool IsPackExpansion1 =
5604 bool IsPackExpansion2 =
5606 if (PackSize1 != PackSize2 && IsPackExpansion1 != IsPackExpansion2) {
5607 if (PackSize1 > PackSize2 && IsPackExpansion1)
5609 if (PackSize1 < PackSize2 && IsPackExpansion2)
5631 if (TPL1->
size() != TPL2->
size() || NumParams1 != NumParams2)
5647 for (
unsigned i = 0; i < NumParams1; ++i)
5663 bool AtLeastAsConstrained1, AtLeastAsConstrained2;
5668 if (AtLeastAsConstrained1 == AtLeastAsConstrained2)
5670 return AtLeastAsConstrained1 ? FT1 : FT2;
5714 bool Complain,
QualType TargetType) {
5715 if (SpecBegin == SpecEnd) {
5717 Diag(Loc, NoneDiag);
5723 if (SpecBegin + 1 == SpecEnd)
5730 = cast<FunctionDecl>(*Best)->getPrimaryTemplate();
5731 assert(BestTemplate &&
"Not a function template specialization?");
5734 = cast<FunctionDecl>(*I)->getPrimaryTemplate();
5735 assert(Challenger &&
"Not a function template specialization?");
5740 BestTemplate = Challenger;
5746 bool Ambiguous =
false;
5749 = cast<FunctionDecl>(*I)->getPrimaryTemplate();
5766 Diag(Loc, AmbigDiag);
5771 const auto *FD = cast<FunctionDecl>(*I);
5773 FD->getPrimaryTemplate()->getTemplateParameters(),
5774 *FD->getTemplateSpecializationArgs());
5775 if (!TargetType.
isNull())
5777 Diag((*I)->getLocation(), PD);
5791template<
typename TemplateLikeDecl>
5793 TemplateLikeDecl *P2,
5822 Deduced.resize(P2->getTemplateParameters()->size());
5824 S, P2->getTemplateParameters(), T2, T1, Info, Deduced,
TDF_None,
5835 const auto *TST1 = cast<TemplateSpecializationType>(T1);
5836 bool AtLeastAsSpecialized;
5838 AtLeastAsSpecialized =
5839 FinishTemplateArgumentDeduction(
5840 S, P2, true, TST1->template_arguments(),
5841 Deduced, Info) == TemplateDeductionResult::Success;
5843 return AtLeastAsSpecialized;
5850 template <
typename T1,
typename T2,
5851 std::enable_if_t<std::is_same_v<T1, T2>,
bool> =
true>
5852 T2 *operator()(T1 *, T2 *P2) {
5855 template <
typename T1,
typename T2,
5856 std::enable_if_t<!std::is_same_v<T1, T2>,
bool> =
true>
5857 T1 *operator()(T1 *, T2 *) {
5863struct TemplateArgumentListAreEqual {
5865 TemplateArgumentListAreEqual(
ASTContext &Ctx) : Ctx(Ctx) {}
5867 template <
typename T1,
typename T2,
5868 std::enable_if_t<std::is_same_v<T1, T2>,
bool> =
true>
5869 bool operator()(T1 *PS1, T2 *PS2) {
5871 Args2 = PS2->getTemplateArgs().asArray();
5873 for (
unsigned I = 0, E = Args1.size(); I < E; ++I) {
5877 llvm::FoldingSetNodeID IDA, IDB;
5878 Args1[I].Profile(IDA, Ctx);
5879 Args2[I].Profile(IDB, Ctx);
5886 template <
typename T1,
typename T2,
5887 std::enable_if_t<!std::is_same_v<T1, T2>,
bool> =
true>
5888 bool operator()(T1 *Spec, T2 *Primary) {
5890 Args2 = Primary->getInjectedTemplateArgs();
5892 for (
unsigned I = 0, E = Args1.size(); I < E; ++I) {
5896 llvm::FoldingSetNodeID IDA, IDB;
5897 Args1[I].Profile(IDA, Ctx);
5931template <
typename TemplateLikeDecl,
typename PrimaryDel>
5932static TemplateLikeDecl *
5935 constexpr bool IsMoreSpecialThanPrimaryCheck =
5936 !std::is_same_v<TemplateLikeDecl, PrimaryDel>;
5939 if (IsMoreSpecialThanPrimaryCheck && !Better1)
5943 if (IsMoreSpecialThanPrimaryCheck && !Better2)
5949 if (Better1 != Better2)
5950 return Better1 ? P1 : GetP2()(P1, P2);
5952 if (!Better1 && !Better2)
5957 auto *TST1 = cast<TemplateSpecializationType>(T1);
5958 auto *TST2 = cast<TemplateSpecializationType>(T2);
5961 assert(TST1->template_arguments().size() ==
5962 TST2->template_arguments().size());
5967 bool IsPackExpansion1 =
5969 bool IsPackExpansion2 =
5971 if (PackSize1 != PackSize2 && IsPackExpansion1 != IsPackExpansion2) {
5972 if (PackSize1 > PackSize2 && IsPackExpansion1)
5973 return GetP2()(P1, P2);
5974 if (PackSize1 < PackSize2 && IsPackExpansion2)
6003 if (!TemplateArgumentListAreEqual(S.
getASTContext())(P1, P2))
6007 P1->getAssociatedConstraints(AC1);
6008 P2->getAssociatedConstraints(AC2);
6009 bool AtLeastAsConstrained1, AtLeastAsConstrained2;
6011 (IsMoreSpecialThanPrimaryCheck && !AtLeastAsConstrained1))
6015 if (AtLeastAsConstrained1 == AtLeastAsConstrained2)
6017 return AtLeastAsConstrained1 ? P1 : GetP2()(P1, P2);
6062 "the partial specializations being compared should specialize"
6063 " the same template.");
6125 for (
unsigned I = 0, N =
P->size(); I != N; ++I) {
6134 Arg,
QualType(),
P->getParam(I)->getLocation()));
6159struct MarkUsedTemplateParameterVisitor :
6161 llvm::SmallBitVector &
Used;
6164 MarkUsedTemplateParameterVisitor(llvm::SmallBitVector &
Used,
6169 if (
T->getDepth() == Depth)
6170 Used[
T->getIndex()] =
true;
6175 if (
auto *TTP = llvm::dyn_cast_or_null<TemplateTemplateParmDecl>(
6177 if (TTP->getDepth() == Depth)
6178 Used[TTP->getIndex()] =
true;
6185 if (
auto *NTTP = dyn_cast<NonTypeTemplateParmDecl>(E->
getDecl()))
6186 if (NTTP->getDepth() == Depth)
6187 Used[NTTP->getIndex()] =
true;
6200 llvm::SmallBitVector &
Used) {
6202 MarkUsedTemplateParameterVisitor(
Used, Depth)
6203 .TraverseStmt(
const_cast<Expr *
>(E));
6209 E = Expansion->getPattern();
6231 llvm::SmallBitVector &
Used) {
6238 OnlyDeduced, Depth,
Used);
6248 llvm::SmallBitVector &
Used) {
6249 if (
TemplateDecl *Template = Name.getAsTemplateDecl()) {
6251 = dyn_cast<TemplateTemplateParmDecl>(Template)) {
6252 if (TTP->getDepth() == Depth)
6253 Used[TTP->getIndex()] =
true;
6272 llvm::SmallBitVector &
Used) {
6284 cast<PointerType>(
T)->getPointeeType(),
6290 case Type::BlockPointer:
6292 cast<BlockPointerType>(
T)->getPointeeType(),
6298 case Type::LValueReference:
6299 case Type::RValueReference:
6301 cast<ReferenceType>(
T)->getPointeeType(),
6307 case Type::MemberPointer: {
6312 OnlyDeduced, Depth,
Used);
6316 case Type::DependentSizedArray:
6318 cast<DependentSizedArrayType>(
T)->getSizeExpr(),
6319 OnlyDeduced, Depth,
Used);
6323 case Type::ConstantArray:
6324 case Type::IncompleteArray:
6325 case Type::ArrayParameter:
6327 cast<ArrayType>(
T)->getElementType(),
6328 OnlyDeduced, Depth,
Used);
6331 case Type::ExtVector:
6333 cast<VectorType>(
T)->getElementType(),
6334 OnlyDeduced, Depth,
Used);
6337 case Type::DependentVector: {
6338 const auto *VecType = cast<DependentVectorType>(
T);
6345 case Type::DependentSizedExtVector: {
6347 = cast<DependentSizedExtVectorType>(
T);
6355 case Type::DependentAddressSpace: {
6357 cast<DependentAddressSpaceType>(
T);
6359 OnlyDeduced, Depth,
Used);
6362 OnlyDeduced, Depth,
Used);
6366 case Type::ConstantMatrix: {
6373 case Type::DependentSizedMatrix: {
6384 case Type::FunctionProto: {
6388 for (
unsigned I = 0, N = Proto->
getNumParams(); I != N; ++I) {
6393 if (!OnlyDeduced || I + 1 == N ||
6411 case Type::TemplateTypeParm: {
6418 case Type::SubstTemplateTypeParmPack: {
6420 = cast<SubstTemplateTypeParmPackType>(
T);
6424 OnlyDeduced, Depth,
Used);
6428 case Type::InjectedClassName:
6429 T = cast<InjectedClassNameType>(
T)->getInjectedSpecializationType();
6432 case Type::TemplateSpecialization: {
6434 = cast<TemplateSpecializationType>(
T);
6454 cast<ComplexType>(
T)->getElementType(),
6455 OnlyDeduced, Depth,
Used);
6461 cast<AtomicType>(
T)->getValueType(),
6462 OnlyDeduced, Depth,
Used);
6465 case Type::DependentName:
6468 cast<DependentNameType>(
T)->getQualifier(),
6469 OnlyDeduced, Depth,
Used);
6472 case Type::DependentTemplateSpecialization: {
6486 = cast<DependentTemplateSpecializationType>(
T);
6489 OnlyDeduced, Depth,
Used);
6499 OnlyDeduced, Depth,
Used);
6502 case Type::TypeOfExpr:
6505 cast<TypeOfExprType>(
T)->getUnderlyingExpr(),
6506 OnlyDeduced, Depth,
Used);
6509 case Type::Decltype:
6512 cast<DecltypeType>(
T)->getUnderlyingExpr(),
6513 OnlyDeduced, Depth,
Used);
6516 case Type::PackIndexing:
6519 OnlyDeduced, Depth,
Used);
6521 OnlyDeduced, Depth,
Used);
6525 case Type::UnaryTransform:
6529 OnlyDeduced, Depth,
Used);
6532 case Type::PackExpansion:
6534 cast<PackExpansionType>(
T)->getPattern(),
6535 OnlyDeduced, Depth,
Used);
6539 case Type::DeducedTemplateSpecialization:
6541 cast<DeducedType>(
T)->getDeducedType(),
6542 OnlyDeduced, Depth,
Used);
6544 case Type::DependentBitInt:
6546 cast<DependentBitIntType>(
T)->getNumBitsExpr(),
6547 OnlyDeduced, Depth,
Used);
6552 case Type::VariableArray:
6553 case Type::FunctionNoProto:
6556 case Type::ObjCInterface:
6557 case Type::ObjCObject:
6558 case Type::ObjCObjectPointer:
6559 case Type::UnresolvedUsing:
6562#define TYPE(Class, Base)
6563#define ABSTRACT_TYPE(Class, Base)
6564#define DEPENDENT_TYPE(Class, Base)
6565#define NON_CANONICAL_TYPE(Class, Base) case Type::Class:
6566#include "clang/AST/TypeNodes.inc"
6578 llvm::SmallBitVector &
Used) {
6596 OnlyDeduced, Depth,
Used);
6621 llvm::SmallBitVector &
Used) {
6636 bool OnlyDeduced,
unsigned Depth,
6637 llvm::SmallBitVector &
Used) {
6646 for (
unsigned I = 0, N = TemplateArgs.
size(); I != N; ++I)
6655 llvm::SmallBitVector &Deduced) {
6659 Deduced.resize(TemplateParams->
size());
6662 for (
unsigned I = 0, N =
Function->getNumParams(); I != N; ++I)
6664 true, TemplateParams->
getDepth(), Deduced);
6675 llvm::SmallBitVector Deduced(TemplateParams->
size());
6679 return Deduced.any();
Defines the clang::ASTContext interface.
This file provides some common utility functions for processing Lambda related AST Constructs.
Provides definitions for the various language-specific address spaces.
static Decl::Kind getKind(const Decl *D)
Defines the C++ Decl subclasses, other than those for templates (found in DeclTemplate....
Defines the C++ template declaration subclasses.
Defines the ExceptionSpecificationType enumeration and various utility functions.
Defines the clang::Expr interface and subclasses for C++ expressions.
llvm::DenseSet< const void * > Visited
Forward-declares and imports various common LLVM datatypes that clang wants to use unqualified.
Defines the clang::LangOptions interface.
Implements a partial diagnostic that can be emitted anwyhere in a DiagnosticBuilder stream.
static QualType getUnderlyingType(const SubRegion *R)
static bool isSameTemplateArg(ASTContext &Context, TemplateArgument X, const TemplateArgument &Y, bool PartialOrdering, bool PackExpansionMatchesPack=false)
Determine whether two template arguments are the same.
static bool isAtLeastAsSpecializedAs(Sema &S, SourceLocation Loc, const FunctionTemplateDecl *FT1, const FunctionTemplateDecl *FT2, TemplatePartialOrderingContext TPOC, bool Reversed, const SmallVector< QualType > &Args1, const SmallVector< QualType > &Args2)
Determine whether the function template FT1 is at least as specialized as FT2.
static bool hasSameExtendedValue(llvm::APSInt X, llvm::APSInt Y)
Compare two APSInts, extending and switching the sign as necessary to compare their values regardless...
static TemplateLikeDecl * getMoreSpecialized(Sema &S, QualType T1, QualType T2, TemplateLikeDecl *P1, PrimaryDel *P2, TemplateDeductionInfo &Info)
Returns the more specialized template specialization between T1/P1 and T2/P2.
static DeducedTemplateArgument checkDeducedTemplateArguments(ASTContext &Context, const DeducedTemplateArgument &X, const DeducedTemplateArgument &Y, bool AggregateCandidateDeduction=false)
Verify that the given, deduced template arguments are compatible.
static bool isSameDeclaration(Decl *X, Decl *Y)
Determine whether two declaration pointers refer to the same declaration.
static CXXRecordDecl * getCanonicalRD(QualType T)
static bool hasTemplateArgumentForDeduction(ArrayRef< TemplateArgument > &Args, unsigned &ArgIdx)
Determine whether there is a template argument to be used for deduction.
static DeclContext * getAsDeclContextOrEnclosing(Decl *D)
static bool hasInconsistentOrSupersetQualifiersOf(QualType ParamType, QualType ArgType)
Determine whether the parameter has qualifiers that the argument lacks.
static void MarkUsedTemplateParameters(ASTContext &Ctx, const TemplateArgument &TemplateArg, bool OnlyDeduced, unsigned Depth, llvm::SmallBitVector &Used)
Mark the template parameters that are used by this template argument.
static QualType GetTypeOfFunction(Sema &S, const OverloadExpr::FindResult &R, FunctionDecl *Fn)
Gets the type of a function for template-argument-deducton purposes when it's considered as part of a...
static TemplateDeductionResult CheckDeducedArgumentConstraints(Sema &S, TemplateDeclT *Template, ArrayRef< TemplateArgument > SugaredDeducedArgs, ArrayRef< TemplateArgument > CanonicalDeducedArgs, TemplateDeductionInfo &Info)
static TemplateDeductionResult DeduceTemplateBases(Sema &S, const CXXRecordDecl *RD, TemplateParameterList *TemplateParams, QualType P, TemplateDeductionInfo &Info, SmallVectorImpl< DeducedTemplateArgument > &Deduced)
Attempt to deduce the template arguments by checking the base types according to (C++20 [temp....
static TemplateDeductionResult DeduceTemplateArguments(Sema &S, TemplateParameterList *TemplateParams, ArrayRef< TemplateArgument > Ps, ArrayRef< TemplateArgument > As, TemplateDeductionInfo &Info, SmallVectorImpl< DeducedTemplateArgument > &Deduced, bool NumberOfArgumentsMustMatch)
static const NonTypeTemplateParmDecl * getDeducedParameterFromExpr(const Expr *E, unsigned Depth)
If the given expression is of a form that permits the deduction of a non-type template parameter,...
static TemplateDeductionResult DeduceTemplateSpecArguments(Sema &S, TemplateParameterList *TemplateParams, const QualType P, QualType A, TemplateDeductionInfo &Info, SmallVectorImpl< DeducedTemplateArgument > &Deduced)
Deduce the template arguments by comparing the template parameter type (which is a template-id) with ...
static bool hasPackExpansionBeforeEnd(ArrayRef< TemplateArgument > Args)
Determine whether the given set of template arguments has a pack expansion that is not the last templ...
static bool isSimpleTemplateIdType(QualType T)
Determine whether the given type T is a simple-template-id type.
static bool ConvertDeducedTemplateArgument(Sema &S, NamedDecl *Param, DeducedTemplateArgument Arg, NamedDecl *Template, TemplateDeductionInfo &Info, bool IsDeduced, SmallVectorImpl< TemplateArgument > &SugaredOutput, SmallVectorImpl< TemplateArgument > &CanonicalOutput)
Convert the given deduced template argument and add it to the set of fully-converted template argumen...
static TemplateParameter makeTemplateParameter(Decl *D)
Helper function to build a TemplateParameter when we don't know its type statically.
static TemplateDeductionResult CheckOriginalCallArgDeduction(Sema &S, TemplateDeductionInfo &Info, Sema::OriginalCallArg OriginalArg, QualType DeducedA)
Check whether the deduced argument type for a call to a function template matches the actual argument...
static TemplateDeductionResult DeduceNullPtrTemplateArgument(Sema &S, TemplateParameterList *TemplateParams, const NonTypeTemplateParmDecl *NTTP, QualType NullPtrType, TemplateDeductionInfo &Info, SmallVectorImpl< DeducedTemplateArgument > &Deduced)
Deduce the value of the given non-type template parameter from the given null pointer template argume...
static unsigned getPackIndexForParam(Sema &S, FunctionTemplateDecl *FunctionTemplate, const MultiLevelTemplateArgumentList &Args, unsigned ParamIdx)
Find the pack index for a particular parameter index in an instantiation of a function template with ...
static bool AdjustFunctionParmAndArgTypesForDeduction(Sema &S, TemplateParameterList *TemplateParams, unsigned FirstInnerIndex, QualType &ParamType, QualType &ArgType, Expr::Classification ArgClassification, Expr *Arg, unsigned &TDF, TemplateSpecCandidateSet *FailedTSC=nullptr)
Perform the adjustments to the parameter and argument types described in C++ [temp....
static TemplateDeductionResult DeduceTemplateArgumentsFromCallArgument(Sema &S, TemplateParameterList *TemplateParams, unsigned FirstInnerIndex, QualType ParamType, QualType ArgType, Expr::Classification ArgClassification, Expr *Arg, TemplateDeductionInfo &Info, SmallVectorImpl< DeducedTemplateArgument > &Deduced, SmallVectorImpl< Sema::OriginalCallArg > &OriginalCallArgs, bool DecomposedParam, unsigned ArgIdx, unsigned TDF, TemplateSpecCandidateSet *FailedTSC=nullptr)
Perform template argument deduction per [temp.deduct.call] for a single parameter / argument pair.
static QualType GetImplicitObjectParameterType(ASTContext &Context, const CXXMethodDecl *Method, QualType RawType, bool IsOtherRvr)
static TemplateDeductionResult DeduceFromInitializerList(Sema &S, TemplateParameterList *TemplateParams, QualType AdjustedParamType, InitListExpr *ILE, TemplateDeductionInfo &Info, SmallVectorImpl< DeducedTemplateArgument > &Deduced, SmallVectorImpl< Sema::OriginalCallArg > &OriginalCallArgs, unsigned ArgIdx, unsigned TDF)
Attempt template argument deduction from an initializer list deemed to be an argument in a function c...
static bool isSameTemplate(TemplateDecl *T1, TemplateDecl *T2)
Determine if the two templates are equivalent.
static unsigned getFirstInnerIndex(FunctionTemplateDecl *FTD)
Get the index of the first template parameter that was originally from the innermost template-paramet...
static TemplateDeductionResult DeduceTemplateArgumentsByTypeMatch(Sema &S, TemplateParameterList *TemplateParams, QualType Param, QualType Arg, TemplateDeductionInfo &Info, SmallVectorImpl< DeducedTemplateArgument > &Deduced, unsigned TDF, bool PartialOrdering=false, bool DeducedFromArrayBound=false)
Deduce the template arguments by comparing the parameter type and the argument type (C++ [temp....
static TemplateDeductionResult DeduceNonTypeTemplateArgument(Sema &S, TemplateParameterList *TemplateParams, const NonTypeTemplateParmDecl *NTTP, const DeducedTemplateArgument &NewDeduced, QualType ValueType, TemplateDeductionInfo &Info, SmallVectorImpl< DeducedTemplateArgument > &Deduced)
Deduce the value of the given non-type template parameter as the given deduced template argument.
static TemplateDeductionResult ConvertDeducedTemplateArguments(Sema &S, TemplateDeclT *Template, bool IsDeduced, SmallVectorImpl< DeducedTemplateArgument > &Deduced, TemplateDeductionInfo &Info, SmallVectorImpl< TemplateArgument > &SugaredBuilder, SmallVectorImpl< TemplateArgument > &CanonicalBuilder, LocalInstantiationScope *CurrentInstantiationScope=nullptr, unsigned NumAlreadyConverted=0, bool PartialOverloading=false)
static bool DeducedArgsNeedReplacement(TemplateDeclT *Template)
static QualType ResolveOverloadForDeduction(Sema &S, TemplateParameterList *TemplateParams, Expr *Arg, QualType ParamType, bool ParamWasReference, TemplateSpecCandidateSet *FailedTSC=nullptr)
Apply the deduction rules for overload sets.
static bool IsPossiblyOpaquelyQualifiedType(QualType T)
Determines whether the given type is an opaque type that might be more qualified when instantiated.
static std::enable_if_t< IsPartialSpecialization< T >::value, TemplateDeductionResult > FinishTemplateArgumentDeduction(Sema &S, T *Partial, bool IsPartialOrdering, ArrayRef< TemplateArgument > TemplateArgs, SmallVectorImpl< DeducedTemplateArgument > &Deduced, TemplateDeductionInfo &Info)
Complete template argument deduction for a partial specialization.
static TemplateDeductionResult instantiateExplicitSpecifierDeferred(Sema &S, FunctionDecl *Specialization, const MultiLevelTemplateArgumentList &SubstArgs, TemplateDeductionInfo &Info, FunctionTemplateDecl *FunctionTemplate, ArrayRef< TemplateArgument > DeducedArgs)
static bool CheckDeducedPlaceholderConstraints(Sema &S, const AutoType &Type, AutoTypeLoc TypeLoc, QualType Deduced)
static bool IsPossiblyOpaquelyQualifiedTypeInternal(const Type *T)
static bool hasDeducibleTemplateParameters(Sema &S, FunctionTemplateDecl *FunctionTemplate, QualType T)
static bool isForwardingReference(QualType Param, unsigned FirstInnerIndex)
Determine whether a type denotes a forwarding reference.
bool DeducedArgsNeedReplacement< VarTemplatePartialSpecializationDecl >(VarTemplatePartialSpecializationDecl *Spec)
bool DeducedArgsNeedReplacement< ClassTemplatePartialSpecializationDecl >(ClassTemplatePartialSpecializationDecl *Spec)
Defines the clang::SourceLocation class and associated facilities.
Defines various enumerations that describe declaration and type specifiers.
Defines the clang::TypeLoc interface and its subclasses.
C Language Family Type Representation.
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
const ConstantArrayType * getAsConstantArrayType(QualType T) const
QualType getRValueReferenceType(QualType T) const
Return the uniqued reference to the type for an rvalue reference to the specified type.
unsigned getIntWidth(QualType T) const
QualType getBlockPointerType(QualType T) const
Return the uniqued reference to the type for a block of the specified type.
TemplateArgument getCanonicalTemplateArgument(const TemplateArgument &Arg) const
Retrieve the "canonical" template argument.
QualType getMemberPointerType(QualType T, const Type *Cls) const
Return the uniqued reference to the type for a member pointer to the specified type in the specified ...
TemplateName getCanonicalTemplateName(const TemplateName &Name) const
Retrieves the "canonical" template name that refers to a given template.
QualType getTemplateSpecializationType(TemplateName T, ArrayRef< TemplateArgument > Args, QualType Canon=QualType()) const
CanQualType getCanonicalType(QualType T) const
Return the canonical (structural) type corresponding to the specified potentially non-canonical type ...
bool hasSameType(QualType T1, QualType T2) const
Determine whether the given types T1 and T2 are equivalent.
void getInjectedTemplateArgs(const TemplateParameterList *Params, SmallVectorImpl< TemplateArgument > &Args)
Get a template argument list with one argument per template parameter in a template parameter list,...
QualType getPointerType(QualType T) const
Return the uniqued reference to the type for a pointer to the specified type.
const IncompleteArrayType * getAsIncompleteArrayType(QualType T) const
bool hasSameFunctionTypeIgnoringExceptionSpec(QualType T, QualType U) const
Determine whether two function types are the same, ignoring exception specifications in cases where t...
QualType getLValueReferenceType(QualType T, bool SpelledAsLValue=true) const
Return the uniqued reference to the type for an lvalue reference to the specified type.
QualType getTypeDeclType(const TypeDecl *Decl, const TypeDecl *PrevDecl=nullptr) const
Return the unique reference to the type for the specified type declaration.
const LangOptions & getLangOpts() const
TemplateArgument getInjectedTemplateArg(NamedDecl *ParamDecl)
QualType getDecayedType(QualType T) const
Return the uniqued reference to the decayed version of the given type.
QualType getCanonicalTemplateSpecializationType(TemplateName T, ArrayRef< TemplateArgument > Args) const
bool hasSameTemplateName(const TemplateName &X, const TemplateName &Y) const
Determine whether the given template names refer to the same template.
TypeSourceInfo * getTrivialTypeSourceInfo(QualType T, SourceLocation Loc=SourceLocation()) const
Allocate a TypeSourceInfo where all locations have been initialized to a given location,...
CanQualType getSizeType() const
Return the unique type for "size_t" (C99 7.17), defined in <stddef.h>.
QualType removeAddrSpaceQualType(QualType T) const
Remove any existing address space on the type and returns the type with qualifiers intact (or that's ...
QualType getQualifiedType(SplitQualType split) const
Un-split a SplitQualType.
QualType getUnqualifiedArrayType(QualType T, Qualifiers &Quals)
Return this type as a completely-unqualified array type, capturing the qualifiers in Quals.
LangAS getDefaultOpenCLPointeeAddrSpace()
Returns default address space based on OpenCL version and enabled features.
bool hasSameUnqualifiedType(QualType T1, QualType T2) const
Determine whether the given types are equivalent after cvr-qualifiers have been removed.
const ArrayType * getAsArrayType(QualType T) const
Type Query functions.
uint64_t getTypeSize(QualType T) const
Return the size of the specified (complete) type T, in bits.
CanQualType UnsignedIntTy
QualType getCommonSugaredType(QualType X, QualType Y, bool Unqualified=false)
QualType getArrayDecayedType(QualType T) const
Return the properly qualified result of decaying the specified array type to a pointer.
QualType getFunctionType(QualType ResultTy, ArrayRef< QualType > Args, const FunctionProtoType::ExtProtoInfo &EPI) const
Return a normal function type with a typed argument list.
QualType getAdjustedParameterType(QualType T) const
Perform adjustment on the parameter type of a function.
QualType getAddrSpaceQualType(QualType T, LangAS AddressSpace) const
Return the uniqued reference to the type for an address space qualified type with the specified type ...
void adjustDeducedFunctionResultType(FunctionDecl *FD, QualType ResultType)
Change the result type of a function type once it is deduced.
const DependentSizedArrayType * getAsDependentSizedArrayType(QualType T) const
The result of parsing/analyzing an expression, statement etc.
Represents a C++11 auto or C++14 decltype(auto) type, possibly constrained by a type-constraint.
ArrayRef< TemplateArgument > getTypeConstraintArguments() const
bool isDecltypeAuto() const
ConceptDecl * getTypeConstraintConcept() const
AutoTypeKeyword getKeyword() const
bool isConstrained() const
A fixed int type of a specified bitwidth.
Represents a C++ conversion function within a class.
QualType getConversionType() const
Returns the type that this conversion function is converting to.
Represents a static or instance method of a struct/union/class.
bool isExplicitObjectMemberFunction() const
[C++2b][dcl.fct]/p7 An explicit object member function is a non-static member function with an explic...
RefQualifierKind getRefQualifier() const
Retrieve the ref-qualifier associated with this method.
Qualifiers getMethodQualifiers() const
The null pointer literal (C++11 [lex.nullptr])
Represents a C++ struct/union/class.
CXXMethodDecl * getLambdaCallOperator() const
Retrieve the lambda call operator of the closure type if this is a closure type.
Declaration of a class template.
QualType getInjectedClassNameSpecialization()
Retrieve the template specialization type of the injected-class-name for this class template.
QualType getInjectedSpecializationType() const
Retrieves the injected specialization type for this partial specialization.
ClassTemplateDecl * getSpecializedTemplate() const
Retrieve the template that this specialization specializes.
bool isClassScopeExplicitSpecialization() const
Is this an explicit specialization at class scope (within the class that owns the primary template)?...
Complex values, per C99 6.2.5p11.
Declaration of a C++20 concept.
const TypeClass * getTypePtr() const
Represents a concrete matrix type with constant number of rows and columns.
unsigned getNumColumns() const
Returns the number of columns in the matrix.
unsigned getNumRows() const
Returns the number of rows in the matrix.
The result of a constraint satisfaction check, containing the necessary information to diagnose an un...
A POD class for pairing a NamedDecl* with an access specifier.
DeclContext - This is used only as base class of specific decl types that can act as declaration cont...
DeclContext * getParent()
getParent - Returns the containing DeclContext.
A reference to a declared variable, function, enum, etc.
Decl - This represents one declaration (or definition), e.g.
FriendObjectKind getFriendObjectKind() const
Determines whether this declaration is the object of a friend declaration and, if so,...
bool isParameterPack() const
Whether this declaration is a parameter pack.
@ FOK_None
Not a friend object.
bool isInvalidDecl() const
SourceLocation getLocation() const
bool isTemplateParameterPack() const
isTemplateParameter - Determines whether this declaration is a template parameter pack.
DeclContext * getDeclContext()
DeclContext * getLexicalDeclContext()
getLexicalDeclContext - The declaration context where this Decl was lexically declared (LexicalDC).
virtual Decl * getCanonicalDecl()
Retrieves the "canonical" declaration of the given declaration.
virtual SourceRange getSourceRange() const LLVM_READONLY
Source range that this declaration covers.
Captures a template argument whose value has been deduced via c++ template argument deduction.
void setDeducedFromArrayBound(bool Deduced)
Specify whether the given non-type template argument was deduced from an array bound.
bool wasDeducedFromArrayBound() const
For a non-type template argument, determine whether the template argument was deduced from an array b...
TemplateName getTemplateName() const
Retrieve the name of the template that we are deducing.
Common base class for placeholders for types that get replaced by placeholder type deduction: C++11 a...
Represents an extended address space qualifier where the input address space value is dependent.
Expr * getAddrSpaceExpr() const
QualType getPointeeType() const
Represents an extended vector type where either the type or size is dependent.
Expr * getSizeExpr() const
QualType getElementType() const
Represents a matrix type where the type and the number of rows and columns is dependent on a template...
Expr * getColumnExpr() const
Expr * getRowExpr() const
Represents a dependent template name that cannot be resolved prior to template instantiation.
Represents a template specialization type whose template cannot be resolved, e.g.
ArrayRef< TemplateArgument > template_arguments() const
NestedNameSpecifier * getQualifier() const
Represents a vector type where either the type or size is dependent.
RAII object that enters a new expression evaluation context.
Store information needed for an explicit specifier.
bool isInvalid() const
Determine if the explicit specifier is invalid.
const Expr * getExpr() const
The return type of classify().
This represents one expression.
bool isValueDependent() const
Determines whether the value of this expression depends on.
SourceLocation getExprLoc() const LLVM_READONLY
getExprLoc - Return the preferred location for the arrow when diagnosing a problem with a generic exp...
std::optional< llvm::APSInt > getIntegerConstantExpr(const ASTContext &Ctx, SourceLocation *Loc=nullptr) const
isIntegerConstantExpr - Return the value if this expression is a valid integer constant expression.
ExtVectorType - Extended vector type.
Stores a list of template parameters and the associated requires-clause (if any) for a TemplateDecl a...
Represents a function declaration or definition.
const ParmVarDecl * getParamDecl(unsigned i) const
FunctionTemplateDecl * getDescribedFunctionTemplate() const
Retrieves the function template that is described by this function declaration.
QualType getReturnType() const
ArrayRef< ParmVarDecl * > parameters() const
FunctionDecl * getTemplateInstantiationPattern(bool ForDefinition=true) const
Retrieve the function declaration from which this function could be instantiated, if it is an instant...
const TemplateArgumentList * getTemplateSpecializationArgs() const
Retrieve the template arguments used to produce this function template specialization from the primar...
bool isImmediateEscalating() const
size_t param_size() const
bool isDefined(const FunctionDecl *&Definition, bool CheckForPendingFriendDefinition=false) const
Returns true if the function has a definition that does not need to be instantiated.
Represents a prototype with parameter type info, e.g.
param_type_iterator param_type_begin() const
const ExtParameterInfo * getExtParameterInfosOrNull() const
Return a pointer to the beginning of the array of extra parameter information, if present,...
unsigned getNumParams() const
bool hasTrailingReturn() const
Whether this function prototype has a trailing return type.
QualType getParamType(unsigned i) const
bool hasExceptionSpec() const
Return whether this function has any kind of exception spec.
ExtProtoInfo getExtProtoInfo() const
Expr * getNoexceptExpr() const
Return the expression inside noexcept(expression), or a null pointer if there is none (because the ex...
param_type_iterator param_type_end() const
ArrayRef< QualType > getParamTypes() const
Declaration of a template function.
FunctionDecl * getTemplatedDecl() const
Get the underlying function declaration of the template.
FunctionType - C99 6.7.5.3 - Function Declarators.
QualType getReturnType() const
const TypeClass * getTypePtr() const
Describes an C or C++ initializer list.
unsigned getNumInits() const
ArrayRef< Expr * > inits()
The injected class name of a C++ class template or class template partial specialization.
An lvalue reference type, per C++11 [dcl.ref].
A C++ lambda expression, which produces a function object (of unspecified type) that can be invoked l...
A stack-allocated class that identifies which local variable declaration instantiations are present i...
void SetPartiallySubstitutedPack(NamedDecl *Pack, const TemplateArgument *ExplicitArgs, unsigned NumExplicitArgs)
Note that the given parameter pack has been partially substituted via explicit specification of templ...
Represents a matrix type, as defined in the Matrix Types clang extensions.
QualType getElementType() const
Returns type of the elements being stored in the matrix.
A pointer to member type per C++ 8.3.3 - Pointers to members.
QualType getPointeeType() const
const Type * getClass() const
Data structure that captures multiple levels of template argument lists for use in template instantia...
void replaceInnermostTemplateArguments(Decl *AssociatedDecl, ArgList Args)
Replaces the current 'innermost' level with the provided argument list.
This represents a decl that may have a name.
NamedDecl * getUnderlyingDecl()
Looks through UsingDecls and ObjCCompatibleAliasDecls for the underlying named decl.
DeclarationName getDeclName() const
Get the actual, stored name of the declaration, which may be a special name.
Class that aids in the construction of nested-name-specifiers along with source-location information ...
Represents a C++ nested name specifier, such as "\::std::vector<int>::".
NestedNameSpecifier * getPrefix() const
Return the prefix of this nested name specifier.
const Type * getAsType() const
Retrieve the type stored in this nested name specifier.
NonTypeTemplateParmDecl - Declares a non-type template parameter, e.g., "Size" in.
bool isExpandedParameterPack() const
Whether this parameter is a non-type template parameter pack that has a known list of different types...
unsigned getIndex() const
Get the index of the template parameter within its parameter list.
unsigned getDepth() const
Get the nesting depth of the template parameter.
Represents a pointer to an Objective C object.
A reference to an overloaded function set, either an UnresolvedLookupExpr or an UnresolvedMemberExpr.
bool hasExplicitTemplateArgs() const
Determines whether this expression had explicit template arguments.
static FindResult find(Expr *E)
Finds the overloaded expression in the given expression E of OverloadTy.
SourceLocation getNameLoc() const
Gets the location of the name.
decls_iterator decls_begin() const
void copyTemplateArgumentsInto(TemplateArgumentListInfo &List) const
Copies the template arguments into the given structure.
decls_iterator decls_end() const
Represents a C++11 pack expansion that produces a sequence of expressions.
Represents a pack expansion of types.
QualType getPattern() const
Retrieve the pattern of this pack expansion, which is the type that will be repeatedly instantiated w...
std::optional< unsigned > getNumExpansions() const
Retrieve the number of expansions that this pack expansion will generate, if known.
bool hasSelectedType() const
QualType getSelectedType() const
A single parameter index whose accessors require each use to make explicit the parameter index encodi...
PointerType - C99 6.7.5.1 - Pointer Declarators.
QualType getPointeeType() const
A (possibly-)qualified type.
bool hasQualifiers() const
Determine whether this type has any qualifiers.
bool isNull() const
Return true if this QualType doesn't point to a type yet.
const Type * getTypePtr() const
Retrieves a pointer to the underlying (unqualified) type.
LangAS getAddressSpace() const
Return the address space of this type.
Qualifiers getQualifiers() const
Retrieve the set of qualifiers applied to this type.
QualType getNonReferenceType() const
If Type is a reference type (e.g., const int&), returns the type that the reference refers to ("const...
QualType getCanonicalType() const
QualType getUnqualifiedType() const
Retrieve the unqualified variant of the given type, removing as little sugar as possible.
bool hasAddressSpace() const
Check if this type has any address space qualifier.
unsigned getCVRQualifiers() const
Retrieve the set of CVR (const-volatile-restrict) qualifiers applied to this type.
Represents a template name that was expressed as a qualified name.
The collection of all-type qualifiers we support.
unsigned getCVRQualifiers() const
void removeCVRQualifiers(unsigned mask)
@ OCL_Strong
Assigning into this object requires the old value to be released and the new value to be retained.
@ OCL_ExplicitNone
This object can be modified without requiring retains or releases.
@ OCL_None
There is no lifetime qualification on this type.
void removeObjCLifetime()
bool isStrictSupersetOf(Qualifiers Other) const
Determine whether this set of qualifiers is a strict superset of another set of qualifiers,...
bool hasNonTrivialObjCLifetime() const
True if the lifetime is neither None or ExplicitNone.
bool hasAddressSpace() const
void removeAddressSpace()
bool hasObjCGCAttr() const
void setCVRQualifiers(unsigned mask)
bool hasObjCLifetime() const
ObjCLifetime getObjCLifetime() const
Qualifiers withoutObjCLifetime() const
bool compatiblyIncludes(Qualifiers other) const
Determines if these qualifiers compatibly include another set.
LangAS getAddressSpace() const
void setObjCLifetime(ObjCLifetime type)
An rvalue reference type, per C++11 [dcl.ref].
A helper class that allows the use of isa/cast/dyncast to detect TagType objects of structs/unions/cl...
RecordDecl * getDecl() const
A class that does preorder or postorder depth-first traversal on the entire Clang AST and visits each...
bool TraverseTemplateName(TemplateName Template)
Recursively visit a template name and dispatch to the appropriate method.
ArrayRef< TemplateArgument > getInjectedTemplateArgs()
Retrieve the "injected" template arguments that correspond to the template parameters of this templat...
Base for LValueReferenceType and RValueReferenceType.
QualType getPointeeType() const
Scope - A scope is a transient data structure that is used while parsing the program.
SemaDiagnosticBuilder Diag(SourceLocation Loc, unsigned DiagID, bool DeferHint=false)
Emit a diagnostic.
RAII object used to change the argument pack substitution index within a Sema object.
RAII object used to temporarily allow the C++ 'this' expression to be used, with the given qualifiers...
A helper class for building up ExtParameterInfos.
const FunctionProtoType::ExtParameterInfo * getPointerOrNull(unsigned numParams)
Return a pointer (suitable for setting in an ExtProtoInfo) to the ExtParameterInfo array we've built ...
RAII class used to determine whether SFINAE has trapped any errors that occur during template argumen...
bool hasErrorOccurred() const
Determine whether any SFINAE errors have been trapped.
Sema - This implements semantic analysis and AST building for C.
bool CheckInstantiatedFunctionTemplateConstraints(SourceLocation PointOfInstantiation, FunctionDecl *Decl, ArrayRef< TemplateArgument > TemplateArgs, ConstraintSatisfaction &Satisfaction)
QualType SubstAutoType(QualType TypeWithAuto, QualType Replacement)
Substitute Replacement for auto in TypeWithAuto.
LocalInstantiationScope * CurrentInstantiationScope
The current instantiation scope used to store local variables.
QualType ReplaceAutoType(QualType TypeWithAuto, QualType Replacement)
Completely replace the auto in TypeWithAuto by Replacement.
bool isTemplateTemplateParameterAtLeastAsSpecializedAs(TemplateParameterList *PParam, TemplateDecl *AArg, SourceLocation Loc)
bool TemplateParameterListsAreEqual(const TemplateCompareNewDeclInfo &NewInstFrom, TemplateParameterList *New, const NamedDecl *OldInstFrom, TemplateParameterList *Old, bool Complain, TemplateParameterListEqualKind Kind, SourceLocation TemplateArgLoc=SourceLocation())
Determine whether the given template parameter lists are equivalent.
TemplateArgumentLoc SubstDefaultTemplateArgumentIfAvailable(TemplateDecl *Template, SourceLocation TemplateLoc, SourceLocation RAngleLoc, Decl *Param, ArrayRef< TemplateArgument > SugaredConverted, ArrayRef< TemplateArgument > CanonicalConverted, bool &HasDefaultArg)
If the given template parameter has a default template argument, substitute into that default templat...
ClassTemplatePartialSpecializationDecl * getMoreSpecializedPartialSpecialization(ClassTemplatePartialSpecializationDecl *PS1, ClassTemplatePartialSpecializationDecl *PS2, SourceLocation Loc)
Returns the more specialized class template partial specialization according to the rules of partial ...
FunctionDecl * InstantiateFunctionDeclaration(FunctionTemplateDecl *FTD, const TemplateArgumentList *Args, SourceLocation Loc, CodeSynthesisContext::SynthesisKind CSC=CodeSynthesisContext::ExplicitTemplateArgumentSubstitution)
Instantiate (or find existing instantiation of) a function template with a given set of template argu...
QualType BuildStdInitializerList(QualType Element, SourceLocation Loc)
Looks for the std::initializer_list template and instantiates it with Element, or emits an error if i...
void SubstExceptionSpec(FunctionDecl *New, const FunctionProtoType *Proto, const MultiLevelTemplateArgumentList &Args)
@ CTAK_DeducedFromArrayBound
The template argument was deduced from an array bound via template argument deduction.
@ CTAK_Specified
The template argument was specified in the code or was instantiated with some deduced template argume...
@ CTAK_Deduced
The template argument was deduced via template argument deduction.
bool DeduceReturnType(FunctionDecl *FD, SourceLocation Loc, bool Diagnose=true)
bool IsQualificationConversion(QualType FromType, QualType ToType, bool CStyle, bool &ObjCLifetimeConversion)
IsQualificationConversion - Determines whether the conversion from an rvalue of type FromType to ToTy...
QualType BuildFunctionType(QualType T, MutableArrayRef< QualType > ParamTypes, SourceLocation Loc, DeclarationName Entity, const FunctionProtoType::ExtProtoInfo &EPI)
Build a function type.
ExprResult BuildExpressionFromNonTypeTemplateArgument(const TemplateArgument &Arg, SourceLocation Loc)
ASTContext & getASTContext() const
UnresolvedSetIterator getMostSpecialized(UnresolvedSetIterator SBegin, UnresolvedSetIterator SEnd, TemplateSpecCandidateSet &FailedCandidates, SourceLocation Loc, const PartialDiagnostic &NoneDiag, const PartialDiagnostic &AmbigDiag, const PartialDiagnostic &CandidateDiag, bool Complain=true, QualType TargetType=QualType())
Retrieve the most specialized of the given function template specializations.
TypeSourceInfo * SubstType(TypeSourceInfo *T, const MultiLevelTemplateArgumentList &TemplateArgs, SourceLocation Loc, DeclarationName Entity, bool AllowDeducedTST=false)
Perform substitution on the type T with a given set of template arguments.
ExprResult ImpCastExprToType(Expr *E, QualType Type, CastKind CK, ExprValueKind VK=VK_PRValue, const CXXCastPath *BasePath=nullptr, CheckedConversionKind CCK=CheckedConversionKind::Implicit)
ImpCastExprToType - If Expr is not of type 'Type', insert an implicit cast.
FunctionDecl * ResolveSingleFunctionTemplateSpecialization(OverloadExpr *ovl, bool Complain=false, DeclAccessPair *Found=nullptr, TemplateSpecCandidateSet *FailedTSC=nullptr)
Given an expression that refers to an overloaded function, try to resolve that overloaded function ex...
PrintingPolicy getPrintingPolicy() const
Retrieve a suitable printing policy for diagnostics.
bool SubstTemplateArguments(ArrayRef< TemplateArgumentLoc > Args, const MultiLevelTemplateArgumentList &TemplateArgs, TemplateArgumentListInfo &Outputs)
@ TPL_TemplateParamsEquivalent
We are determining whether the template-parameters are equivalent according to C++ [temp....
bool isSameOrCompatibleFunctionType(QualType Param, QualType Arg)
Compare types for equality with respect to possibly compatible function types (noreturn adjustment,...
const LangOptions & getLangOpts() const
const FunctionProtoType * ResolveExceptionSpec(SourceLocation Loc, const FunctionProtoType *FPT)
void collectUnexpandedParameterPacks(TemplateArgument Arg, SmallVectorImpl< UnexpandedParameterPack > &Unexpanded)
Collect the set of unexpanded parameter packs within the given template argument.
bool CheckConstraintSatisfaction(const NamedDecl *Template, ArrayRef< const Expr * > ConstraintExprs, const MultiLevelTemplateArgumentList &TemplateArgLists, SourceRange TemplateIDRange, ConstraintSatisfaction &Satisfaction)
Check whether the given list of constraint expressions are satisfied (as if in a 'conjunction') given...
FunctionTemplateDecl * getMoreSpecializedTemplate(FunctionTemplateDecl *FT1, FunctionTemplateDecl *FT2, SourceLocation Loc, TemplatePartialOrderingContext TPOC, unsigned NumCallArguments1, QualType RawObj1Ty={}, QualType RawObj2Ty={}, bool Reversed=false)
Returns the more specialized function template according to the rules of function template partial or...
std::optional< unsigned > getNumArgumentsInExpansion(QualType T, const MultiLevelTemplateArgumentList &TemplateArgs)
Determine the number of arguments in the given pack expansion type.
TemplateArgumentLoc getTrivialTemplateArgumentLoc(const TemplateArgument &Arg, QualType NTTPType, SourceLocation Loc)
Allocate a TemplateArgumentLoc where all locations have been initialized to the given location.
ExplicitSpecifier instantiateExplicitSpecifier(const MultiLevelTemplateArgumentList &TemplateArgs, ExplicitSpecifier ES)
TemplateDeductionResult SubstituteExplicitTemplateArguments(FunctionTemplateDecl *FunctionTemplate, TemplateArgumentListInfo &ExplicitTemplateArgs, SmallVectorImpl< DeducedTemplateArgument > &Deduced, SmallVectorImpl< QualType > &ParamTypes, QualType *FunctionType, sema::TemplateDeductionInfo &Info)
Substitute the explicitly-provided template arguments into the given function template according to C...
bool SubstParmTypes(SourceLocation Loc, ArrayRef< ParmVarDecl * > Params, const FunctionProtoType::ExtParameterInfo *ExtParamInfos, const MultiLevelTemplateArgumentList &TemplateArgs, SmallVectorImpl< QualType > &ParamTypes, SmallVectorImpl< ParmVarDecl * > *OutParams, ExtParameterInfoBuilder &ParamInfos)
Substitute the given template arguments into the given set of parameters, producing the set of parame...
void DiagnoseAutoDeductionFailure(VarDecl *VDecl, Expr *Init)
FunctionDecl * resolveAddressOfSingleOverloadCandidate(Expr *E, DeclAccessPair &FoundResult)
Given an expression that refers to an overloaded function, try to resolve that function to a single f...
DeclContext * CurContext
CurContext - This is the current declaration context of parsing.
SuppressedDiagnosticsMap SuppressedDiagnostics
QualType getDecltypeForExpr(Expr *E)
getDecltypeForExpr - Given an expr, will return the decltype for that expression, according to the ru...
ExprResult CheckPlaceholderExpr(Expr *E)
Check for operands with placeholder types and complain if found.
Decl * SubstDecl(Decl *D, DeclContext *Owner, const MultiLevelTemplateArgumentList &TemplateArgs)
TypeSourceInfo * SubstAutoTypeSourceInfoDependent(TypeSourceInfo *TypeWithAuto)
bool IsAtLeastAsConstrained(NamedDecl *D1, MutableArrayRef< const Expr * > AC1, NamedDecl *D2, MutableArrayRef< const Expr * > AC2, bool &Result)
Check whether the given declaration's associated constraints are at least as constrained than another...
TypeSourceInfo * ReplaceAutoTypeSourceInfo(TypeSourceInfo *TypeWithAuto, QualType Replacement)
bool isCompleteType(SourceLocation Loc, QualType T, CompleteTypeKind Kind=CompleteTypeKind::Default)
bool isStdInitializerList(QualType Ty, QualType *Element)
Tests whether Ty is an instance of std::initializer_list and, if it is and Element is not NULL,...
void InstantiateFunctionDefinition(SourceLocation PointOfInstantiation, FunctionDecl *Function, bool Recursive=false, bool DefinitionRequired=false, bool AtEndOfTU=false)
Instantiate the definition of the given function from its template.
bool CheckTemplateArgumentList(TemplateDecl *Template, SourceLocation TemplateLoc, TemplateArgumentListInfo &TemplateArgs, bool PartialTemplateArgs, SmallVectorImpl< TemplateArgument > &SugaredConverted, SmallVectorImpl< TemplateArgument > &CanonicalConverted, bool UpdateArgsWithConversions=true, bool *ConstraintsNotSatisfied=nullptr)
Check that the given template arguments can be provided to the given template, converting the argumen...
void MarkUsedTemplateParameters(const Expr *E, bool OnlyDeduced, unsigned Depth, llvm::SmallBitVector &Used)
Mark which template parameters are used in a given expression.
@ Unevaluated
The current expression and its subexpressions occur within an unevaluated operand (C++11 [expr]p7),...
bool CheckTemplateArgument(NamedDecl *Param, TemplateArgumentLoc &Arg, NamedDecl *Template, SourceLocation TemplateLoc, SourceLocation RAngleLoc, unsigned ArgumentPackIndex, SmallVectorImpl< TemplateArgument > &SugaredConverted, SmallVectorImpl< TemplateArgument > &CanonicalConverted, CheckTemplateArgumentKind CTAK)
Check that the given template argument corresponds to the given template parameter.
QualType getLambdaConversionFunctionResultType(const FunctionProtoType *CallOpType, CallingConv CC)
Get the return type to use for a lambda's conversion function(s) to function pointer type,...
QualType getCompletedType(Expr *E)
Get the type of expression E, triggering instantiation to complete the type if necessary – that is,...
TypeSourceInfo * SubstAutoTypeSourceInfo(TypeSourceInfo *TypeWithAuto, QualType Replacement)
Substitute Replacement for auto in TypeWithAuto.
TemplateArgumentLoc getIdentityTemplateArgumentLoc(NamedDecl *Param, SourceLocation Location)
Get a template argument mapping the given template parameter to itself, e.g.
bool CheckIfFunctionSpecializationIsImmediate(FunctionDecl *FD, SourceLocation Loc)
QualType SubstAutoTypeDependent(QualType TypeWithAuto)
TemplateDeductionResult DeduceTemplateArguments(ClassTemplatePartialSpecializationDecl *Partial, ArrayRef< TemplateArgument > TemplateArgs, sema::TemplateDeductionInfo &Info)
TemplateDeductionResult FinishTemplateArgumentDeduction(FunctionTemplateDecl *FunctionTemplate, SmallVectorImpl< DeducedTemplateArgument > &Deduced, unsigned NumExplicitlySpecified, FunctionDecl *&Specialization, sema::TemplateDeductionInfo &Info, SmallVectorImpl< OriginalCallArg > const *OriginalCallArgs=nullptr, bool PartialOverloading=false, llvm::function_ref< bool()> CheckNonDependent=[] { return false;})
Finish template argument deduction for a function template, checking the deduced template arguments f...
void runWithSufficientStackSpace(SourceLocation Loc, llvm::function_ref< void()> Fn)
Run some code with "sufficient" stack space.
bool isMoreSpecializedThanPrimary(ClassTemplatePartialSpecializationDecl *T, sema::TemplateDeductionInfo &Info)
std::string getTemplateArgumentBindingsText(const TemplateParameterList *Params, const TemplateArgumentList &Args)
Produces a formatted string that describes the binding of template parameters to template arguments.
void DiagnoseUnsatisfiedConstraint(const ConstraintSatisfaction &Satisfaction, bool First=true)
Emit diagnostics explaining why a constraint expression was deemed unsatisfied.
void adjustMemberFunctionCC(QualType &T, bool HasThisPointer, bool IsCtorOrDtor, SourceLocation Loc)
Adjust the calling convention of a method to be the ABI default if it wasn't specified explicitly.
ExprResult BuildExpressionFromDeclTemplateArgument(const TemplateArgument &Arg, QualType ParamType, SourceLocation Loc)
Given a non-type template argument that refers to a declaration and the type of its corresponding non...
bool IsDerivedFrom(SourceLocation Loc, QualType Derived, QualType Base)
Determine whether the type Derived is a C++ class that is derived from the type Base.
@ Diagnose
Diagnose issues that are non-constant or that are extensions.
TemplateDeductionResult DeduceAutoType(TypeLoc AutoTypeLoc, Expr *Initializer, QualType &Result, sema::TemplateDeductionInfo &Info, bool DependentDeduction=false, bool IgnoreConstraints=false, TemplateSpecCandidateSet *FailedTSC=nullptr)
Deduce the type for an auto type-specifier (C++11 [dcl.spec.auto]p6)
QualType adjustCCAndNoReturn(QualType ArgFunctionType, QualType FunctionType, bool AdjustExceptionSpec=false)
Adjust the type ArgFunctionType to match the calling convention, noreturn, and optionally the excepti...
void HandleFunctionTypeMismatch(PartialDiagnostic &PDiag, QualType FromType, QualType ToType)
HandleFunctionTypeMismatch - Gives diagnostic information for differeing function types.
bool IsFunctionConversion(QualType FromType, QualType ToType, QualType &ResultTy)
Determine whether the conversion from FromType to ToType is a valid conversion that strips "noexcept"...
MultiLevelTemplateArgumentList getTemplateInstantiationArgs(const NamedDecl *D, const DeclContext *DC=nullptr, bool Final=false, std::optional< ArrayRef< TemplateArgument > > Innermost=std::nullopt, bool RelativeToPrimary=false, const FunctionDecl *Pattern=nullptr, bool ForConstraintInstantiation=false, bool SkipForSpecialization=false)
Retrieve the template argument list(s) that should be used to instantiate the definition of the given...
void MarkDeducedTemplateParameters(const FunctionTemplateDecl *FunctionTemplate, llvm::SmallBitVector &Deduced)
Encodes a location in the source.
A trivial tuple used to represent a source range.
SourceLocation getEnd() const
void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Context, bool Canonical, bool ProfileLambdaExpr=false) const
Produce a unique representation of the given statement.
Represents the result of substituting a set of types for a template type parameter pack.
TemplateArgument getArgumentPack() const
unsigned getIndex() const
Returns the index of the replaced parameter in the associated declaration.
const TemplateTypeParmDecl * getReplacedParameter() const
Gets the template parameter declaration that was substituted for.
TagDecl * getCanonicalDecl() override
Retrieves the "canonical" declaration of the given declaration.
A convenient class for passing around template argument information.
void addArgument(const TemplateArgumentLoc &Loc)
A template argument list.
static TemplateArgumentList * CreateCopy(ASTContext &Context, ArrayRef< TemplateArgument > Args)
Create a new template argument list that copies the given set of template arguments.
unsigned size() const
Retrieve the number of template arguments in this template argument list.
const TemplateArgument & get(unsigned Idx) const
Retrieve the template argument at a given index.
ArrayRef< TemplateArgument > asArray() const
Produce this as an array ref.
Location wrapper for a TemplateArgument.
const TemplateArgument & getArgument() const
Represents a template argument.
QualType getParamTypeForDecl() const
Expr * getAsExpr() const
Retrieve the template argument as an expression.
pack_iterator pack_end() const
Iterator referencing one past the last argument of a template argument pack.
pack_iterator pack_begin() const
Iterator referencing the first argument of a template argument pack.
QualType getNonTypeTemplateArgumentType() const
If this is a non-type template argument, get its type.
void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Context) const
Used to insert TemplateArguments into FoldingSets.
QualType getAsType() const
Retrieve the type for a type template argument.
llvm::APSInt getAsIntegral() const
Retrieve the template argument as an integral value.
QualType getNullPtrType() const
Retrieve the type for null non-type template argument.
static TemplateArgument CreatePackCopy(ASTContext &Context, ArrayRef< TemplateArgument > Args)
Create a new template argument pack by copying the given set of template arguments.
TemplateName getAsTemplate() const
Retrieve the template name for a template name argument.
TemplateArgument getPackExpansionPattern() const
When the template argument is a pack expansion, returns the pattern of the pack expansion.
bool isNull() const
Determine whether this template argument has no value.
static TemplateArgument getEmptyPack()
unsigned pack_size() const
The number of template arguments in the given template argument pack.
bool structurallyEquals(const TemplateArgument &Other) const
Determines whether two template arguments are superficially the same.
ValueDecl * getAsDecl() const
Retrieve the declaration for a declaration non-type template argument.
ArrayRef< TemplateArgument > pack_elements() const
Iterator range referencing all of the elements of a template argument pack.
@ Declaration
The template argument is a declaration that was provided for a pointer, reference,...
@ Template
The template argument is a template name that was provided for a template template parameter.
@ StructuralValue
The template argument is a non-type template argument that can't be represented by the special-case D...
@ Pack
The template argument is actually a parameter pack.
@ TemplateExpansion
The template argument is a pack expansion of a template name that was provided for a template templat...
@ NullPtr
The template argument is a null pointer or null pointer to member that was provided for a non-type te...
@ Type
The template argument is a type.
@ Null
Represents an empty template argument, e.g., one that has not been deduced.
@ Integral
The template argument is an integral value stored in an llvm::APSInt that was provided for an integra...
@ Expression
The template argument is an expression, and we've not resolved it to one of the other forms yet,...
ArgKind getKind() const
Return the kind of stored template argument.
bool isPackExpansion() const
Determine whether this template argument is a pack expansion.
TemplateName getAsTemplateOrTemplatePattern() const
Retrieve the template argument as a template name; if the argument is a pack expansion,...
The base class of all kinds of template declarations (e.g., class, function, etc.).
SourceRange getSourceRange() const override LLVM_READONLY
Source range that this declaration covers.
void getAssociatedConstraints(llvm::SmallVectorImpl< const Expr * > &AC) const
Get the total constraint-expression associated with this template, including constraint-expressions d...
TemplateParameterList * getTemplateParameters() const
Get the list of template parameters.
Represents a C++ template name within the type system.
TemplateDecl * getAsTemplateDecl() const
Retrieve the underlying template declaration that this template name refers to, if known.
DependentTemplateName * getAsDependentTemplateName() const
Retrieve the underlying dependent template name structure, if any.
QualifiedTemplateName * getAsQualifiedTemplateName() const
Retrieve the underlying qualified template name structure, if any.
void * getAsVoidPointer() const
Retrieve the template name as a void pointer.
Stores a list of template parameters for a TemplateDecl and its derived classes.
NamedDecl * getParam(unsigned Idx)
unsigned getDepth() const
Get the depth of this template parameter list in the set of template parameter lists.
TemplateSpecCandidateSet - A set of generalized overload candidates, used in template specializations...
void NoteCandidates(Sema &S, SourceLocation Loc)
NoteCandidates - When no template specialization match is found, prints diagnostic messages containin...
Represents a type template specialization; the template must be a class template, a type alias templa...
ArrayRef< TemplateArgument > template_arguments() const
TemplateName getTemplateName() const
Retrieve the name of the template that we are specializing.
TemplateTemplateParmDecl - Declares a template template parameter, e.g., "T" in.
Declaration of a template type parameter.
static TemplateTypeParmDecl * Create(const ASTContext &C, DeclContext *DC, SourceLocation KeyLoc, SourceLocation NameLoc, unsigned D, unsigned P, IdentifierInfo *Id, bool Typename, bool ParameterPack, bool HasTypeConstraint=false, std::optional< unsigned > NumExpanded=std::nullopt)
unsigned getDepth() const
Retrieve the depth of the template parameter.
Wrapper for template type parameters.
unsigned getIndex() const
unsigned getDepth() const
const Type * getTypeForDecl() const
TyLocType push(QualType T)
Pushes space for a new TypeLoc of the given type.
void reserve(size_t Requested)
Ensures that this buffer has at least as much capacity as described.
Base wrapper for a particular "section" of type source info.
SourceRange getLocalSourceRange() const
Get the local source range.
unsigned getFullDataSize() const
Returns the size of the type source info data block.
void copy(TypeLoc other)
Copies the other type loc into this one.
A container of type source information.
SourceLocation getNameLoc() const
void setNameLoc(SourceLocation Loc)
The base class of the type hierarchy.
bool isIncompleteArrayType() const
bool isPlaceholderType() const
Test for a type which does not represent an actual type-system type but is instead used as a placehol...
bool isRValueReferenceType() const
bool canDecayToPointerType() const
Determines whether this type can decay to a pointer type.
bool isFunctionPointerType() const
bool isPointerType() const
const T * castAs() const
Member-template castAs<specific type>.
bool isReferenceType() const
QualType getPointeeType() const
If this is a pointer, ObjC object pointer, or block pointer, this returns the respective pointee.
AutoType * getContainedAutoType() const
Get the AutoType whose type will be deduced for a variable with an initializer of this type.
bool isLValueReferenceType() const
bool isDependentType() const
Whether this type is a dependent type, meaning that its definition somehow depends on a template para...
QualType getCanonicalTypeInternal() const
bool isMemberPointerType() const
bool isObjCLifetimeType() const
Returns true if objects of this type have lifetime semantics under ARC.
bool isUndeducedType() const
Determine whether this type is an undeduced type, meaning that it somehow involves a C++11 'auto' typ...
bool isFunctionType() const
bool isObjCObjectPointerType() const
bool isMemberFunctionPointerType() const
bool isAnyPointerType() const
TypeClass getTypeClass() const
bool isCanonicalUnqualified() const
Determines if this type would be canonical if it had no further qualification.
const T * getAs() const
Member-template getAs<specific type>'.
bool isRecordType() const
The iterator over UnresolvedSets.
Represent the declaration of a variable (in which case it is an lvalue) a function (in which case it ...
Represents a variable declaration or definition.
bool isInitCapture() const
Whether this variable is the implicit variable for a lambda init-capture.
Declaration of a variable template.
const TemplateArgumentList & getTemplateArgs() const
Retrieve the template arguments of the variable template specialization.
bool isClassScopeExplicitSpecialization() const
VarTemplateDecl * getSpecializedTemplate() const
Retrieve the template that this specialization specializes.
Represents a GCC generic vector type.
Provides information about an attempted template argument deduction, whose success or failure was des...
void setExplicitArgs(TemplateArgumentList *NewDeducedSugared, TemplateArgumentList *NewDeducedCanonical)
Provide an initial template argument list that contains the explicitly-specified arguments.
TemplateArgumentList * takeCanonical()
TemplateArgumentList * takeSugared()
Take ownership of the deduced template argument lists.
SourceLocation getLocation() const
Returns the location at which template argument is occurring.
void clearSFINAEDiagnostic()
Discard any SFINAE diagnostics.
TemplateArgument SecondArg
The second template argument to which the template argument deduction failure refers.
TemplateParameter Param
The template parameter to which a template argument deduction failure refers.
diag_iterator diag_end() const
Returns an iterator at the end of the sequence of suppressed diagnostics.
void reset(TemplateArgumentList *NewDeducedSugared, TemplateArgumentList *NewDeducedCanonical)
Provide a new template argument list that contains the results of template argument deduction.
unsigned getDeducedDepth() const
The depth of template parameters for which deduction is being performed.
diag_iterator diag_begin() const
Returns an iterator at the beginning of the sequence of suppressed diagnostics.
TemplateArgument FirstArg
The first template argument to which the template argument deduction failure refers.
ConstraintSatisfaction AssociatedConstraintsSatisfaction
The constraint satisfaction details resulting from the associated constraints satisfaction tests.
unsigned CallArgIndex
The index of the function argument that caused a deduction failure.
The JSON file list parser is used to communicate input to InstallAPI.
bool isTargetAddressSpace(LangAS AS)
@ Specialization
We are substituting template parameters for template arguments in order to form a template specializa...
bool isUnresolvedExceptionSpec(ExceptionSpecificationType ESpecType)
@ RQ_None
No ref-qualifier was provided.
@ RQ_RValue
An rvalue ref-qualifier was provided (&&).
unsigned toTargetAddressSpace(LangAS AS)
@ Result
The result type of a method or function.
llvm::PointerUnion< TemplateTypeParmDecl *, NonTypeTemplateParmDecl *, TemplateTemplateParmDecl * > TemplateParameter
Stores a template parameter of any kind.
std::pair< unsigned, unsigned > getDepthAndIndex(NamedDecl *ND)
Retrieve the depth and index of a template parameter.
std::optional< unsigned > getExpandedPackSize(const NamedDecl *Param)
Check whether the template parameter is a pack expansion, and if so, determine the number of paramete...
bool isLambdaConversionOperator(CXXConversionDecl *C)
const FunctionProtoType * T
void printTemplateArgumentList(raw_ostream &OS, ArrayRef< TemplateArgument > Args, const PrintingPolicy &Policy, const TemplateParameterList *TPL=nullptr)
Print a template argument list, including the '<' and '>' enclosing the template arguments.
TPOC
The context in which partial ordering of function templates occurs.
@ TPOC_Conversion
Partial ordering of function templates for a call to a conversion function.
@ TPOC_Other
Partial ordering of function templates in other contexts, e.g., taking the address of a function temp...
@ TPOC_Call
Partial ordering of function templates for a function call.
TemplateDeductionResult
Describes the result of template argument deduction.
@ MiscellaneousDeductionFailure
Deduction failed; that's all we know.
@ NonDependentConversionFailure
Checking non-dependent argument conversions failed.
@ ConstraintsNotSatisfied
The deduced arguments did not satisfy the constraints associated with the template.
@ Underqualified
Template argument deduction failed due to inconsistent cv-qualifiers on a template parameter type tha...
@ InstantiationDepth
Template argument deduction exceeded the maximum template instantiation depth (which has already been...
@ InvalidExplicitArguments
The explicitly-specified template arguments were not valid template arguments for the given template.
@ TooFewArguments
When performing template argument deduction for a function template, there were too few call argument...
@ Incomplete
Template argument deduction did not deduce a value for every template parameter.
@ Invalid
The declaration was invalid; do nothing.
@ Success
Template argument deduction was successful.
@ SubstitutionFailure
Substitution of the deduced template argument values resulted in an error.
@ IncompletePack
Template argument deduction did not deduce a value for every expansion of an expanded template parame...
@ DeducedMismatch
After substituting deduced template arguments, a dependent parameter type did not match the correspon...
@ Inconsistent
Template argument deduction produced inconsistent deduced values for the given template parameter.
@ TooManyArguments
When performing template argument deduction for a function template, there were too many call argumen...
@ AlreadyDiagnosed
Some error which was already diagnosed.
@ DeducedMismatchNested
After substituting deduced template arguments, an element of a dependent parameter type did not match...
@ NonDeducedMismatch
A non-depnedent component of the parameter did not match the corresponding component of the argument.
CallingConv
CallingConv - Specifies the calling convention that a function uses.
@ EST_Uninstantiated
not instantiated yet
TemplateDeductionFlags
Various flags that control template argument deduction.
@ TDF_None
No template argument deduction flags, which indicates the strictest results for template argument ded...
@ TDF_DerivedClass
Within template argument deduction from a function call, we are matching in a case where we can perfo...
@ TDF_TopLevelParameterTypeList
Whether we are performing template argument deduction for parameters and arguments in a top-level tem...
@ TDF_IgnoreQualifiers
Within template argument deduction from a function call, we are matching in a case where we ignore cv...
@ TDF_ParamWithReferenceType
Within template argument deduction from a function call, we are matching with a parameter type for wh...
@ TDF_SkipNonDependent
Allow non-dependent types to differ, e.g., when performing template argument deduction from a functio...
@ TDF_AllowCompatibleFunctionType
Within template argument deduction from overload resolution per C++ [over.over] allow matching functi...
@ TDF_ArgWithReferenceType
Within template argument deduction for a conversion function, we are matching with an argument type f...
ActionResult< CXXBaseSpecifier * > BaseResult
Represents an explicit template argument list in C++, e.g., the "<int>" in "sort<int>".
SourceLocation RAngleLoc
The source location of the right angle bracket ('>').
SourceLocation LAngleLoc
The source location of the left angle bracket ('<').
llvm::ArrayRef< TemplateArgumentLoc > arguments() const
A pack that we're currently deducing.
DeducedPack(unsigned Index)
SmallVector< DeducedTemplateArgument, 4 > New
DeducedTemplateArgument Saved
DeducedTemplateArgument DeferredDeduction
Holds information about the various types of exception specification.
ExceptionSpecificationType Type
The kind of exception specification this is.
Extra information about a function prototype.
const ExtParameterInfo * ExtParameterInfos
FunctionType::ExtInfo ExtInfo
bool HasFormOfMemberPointer
OverloadExpr * Expression
@ ExplicitTemplateArgumentSubstitution
We are substituting explicit template arguments provided for a function template.
@ DeducedTemplateArgumentSubstitution
We are substituting template argument determined as part of template argument deduction for either a ...
A stack object to be created when performing template instantiation.
bool isInvalid() const
Determines whether we have exceeded the maximum recursive template instantiations.
brief A function argument from which we performed template argument
QualType OriginalParamType
Location information for a TemplateArgument.