45#include "llvm/ADT/APInt.h"
46#include "llvm/ADT/APSInt.h"
47#include "llvm/ADT/ArrayRef.h"
48#include "llvm/ADT/DenseMap.h"
49#include "llvm/ADT/FoldingSet.h"
50#include "llvm/ADT/SmallBitVector.h"
51#include "llvm/ADT/SmallPtrSet.h"
52#include "llvm/ADT/SmallVector.h"
53#include "llvm/Support/Casting.h"
54#include "llvm/Support/Compiler.h"
55#include "llvm/Support/ErrorHandling.h"
113using namespace clang;
119 if (Y.getBitWidth() >
X.getBitWidth())
120 X =
X.extend(Y.getBitWidth());
121 else if (Y.getBitWidth() <
X.getBitWidth())
122 Y = Y.extend(
X.getBitWidth());
125 if (
X.isSigned() != Y.isSigned()) {
127 if ((Y.isSigned() && Y.isNegative()) || (
X.isSigned() &&
X.isNegative()))
150 bool NumberOfArgumentsMustMatch,
155 bool OnlyDeduced,
unsigned Depth,
156 llvm::SmallBitVector &
Used);
159 bool OnlyDeduced,
unsigned Level,
160 llvm::SmallBitVector &Deduced);
170 if (
const auto *IC = dyn_cast<ImplicitCastExpr>(
E))
171 E = IC->getSubExpr();
172 else if (
const auto *CE = dyn_cast<ConstantExpr>(
E))
173 E = CE->getSubExpr();
174 else if (
const auto *Subst = dyn_cast<SubstNonTypeTemplateParmExpr>(
E))
175 E = Subst->getReplacement();
176 else if (
const auto *CCE = dyn_cast<CXXConstructExpr>(
E)) {
178 if (CCE->getParenOrBraceRange().isValid())
181 assert(CCE->getNumArgs() >= 1 &&
"implicit construct expr should have 1 arg");
187 if (
const auto *DRE = dyn_cast<DeclRefExpr>(
E))
188 if (
const auto *NTTP = dyn_cast<NonTypeTemplateParmDecl>(DRE->getDecl()))
189 if (NTTP->getDepth() == Depth)
204 X = NX->getUnderlyingDecl();
205 if (
NamedDecl *NY = dyn_cast<NamedDecl>(Y))
206 Y = NY->getUnderlyingDecl();
219 bool AggregateCandidateDeduction =
false) {
232 QualType XType =
X.getNonTypeTemplateArgumentType();
240 switch (
X.getKind()) {
242 llvm_unreachable(
"Non-deduced template arguments handled above");
249 X.wasDeducedFromArrayBound() ||
255 return X.wasDeducedFromArrayBound() ? Y :
X;
269 return X.wasDeducedFromArrayBound() ? Y :
X;
278 X.structurallyEquals(Y)))
306 llvm::FoldingSetNodeID ID1, ID2;
307 X.getAsExpr()->Profile(ID1, Context,
true);
310 return X.wasDeducedFromArrayBound() ? Y :
X;
317 assert(!
X.wasDeducedFromArrayBound());
330 X.getParamTypeForDecl());
367 (!AggregateCandidateDeduction &&
X.pack_size() != Y.
pack_size()))
374 XA != XAEnd; ++XA, ++YA) {
379 if (Merged.isNull() && !(XA->isNull() && YA->isNull()))
381 NewPack.push_back(Merged);
383 NewPack.push_back(*XA);
393 llvm_unreachable(
"Invalid TemplateArgument Kind!");
406 "deducing non-type template argument with wrong depth");
410 if (Result.isNull()) {
414 return TemplateDeductionResult::Inconsistent;
419 return TemplateDeductionResult::Success;
426 return TemplateDeductionResult::Success;
431 if (
auto *Expansion = dyn_cast<PackExpansionType>(ParamType))
432 ParamType = Expansion->getPattern();
446 S, TemplateParams, ParamType, ValueType, Info, Deduced,
459 S, TemplateParams, NTTP,
461 DeducedFromArrayBound),
462 ValueType, Info, Deduced);
520 case Decl::TemplateTypeParm: {
521 auto *
T = cast<TemplateTypeParmDecl>(A);
524 T->getDepth(),
T->getIndex(),
T->getIdentifier(),
525 T->wasDeclaredWithTypename(),
T->isParameterPack(),
526 T->hasTypeConstraint());
527 R->setDefaultArgument(
530 if (R->hasTypeConstraint()) {
531 auto *
C = R->getTypeConstraint();
532 R->setTypeConstraint(
C->getConceptReference(),
533 C->getImmediatelyDeclaredConstraint());
537 case Decl::NonTypeTemplateParm: {
538 auto *
T = cast<NonTypeTemplateParmDecl>(A);
541 T->getDepth(),
T->getIndex(),
T->getIdentifier(),
T->getType(),
542 T->isParameterPack(),
T->getTypeSourceInfo());
543 R->setDefaultArgument(S.
Context,
547 if (
auto *PTC =
T->getPlaceholderTypeConstraint())
548 R->setPlaceholderTypeConstraint(PTC);
551 case Decl::TemplateTemplateParm: {
552 auto *
T = cast<TemplateTemplateParmDecl>(A);
555 T->getIndex(),
T->isParameterPack(),
T->getIdentifier(),
556 T->wasDeclaredWithTypename(),
T->getTemplateParameters());
557 R->setDefaultArgument(
563 llvm_unreachable(
"Unexpected Decl Kind");
577 return TemplateDeductionResult::Success;
580 if (
auto *TempParam = dyn_cast<TemplateTemplateParmDecl>(ParamDecl)) {
583 return TemplateDeductionResult::Success;
590 if (
auto *TempArg = dyn_cast_or_null<TemplateTemplateParmDecl>(
592 assert(!TempArg->isExpandedParameterPack());
595 if (DefaultArguments.size() != 0) {
596 assert(DefaultArguments.size() <= As->
size());
598 for (
unsigned I = 0; I < DefaultArguments.size(); ++I)
600 DefaultArguments[I]);
601 for (
unsigned I = DefaultArguments.size(); I < As->size(); ++I)
606 auto *TPL = TemplateParameterList::Create(
612 TempArg->getDepth(), TempArg->getPosition(),
613 TempArg->isParameterPack(), TempArg->getIdentifier(),
614 TempArg->wasDeclaredWithTypename(), TPL)));
619 Deduced[TempParam->getIndex()],
621 if (Result.isNull()) {
622 Info.
Param = TempParam;
623 Info.
FirstArg = Deduced[TempParam->getIndex()];
625 return TemplateDeductionResult::Inconsistent;
628 Deduced[TempParam->getIndex()] = Result;
629 return TemplateDeductionResult::Success;
634 return TemplateDeductionResult::Success;
639 return TemplateDeductionResult::NonDeducedMismatch;
665 assert(TST &&
"Expected a TemplateSpecializationType");
679 UP = IP->getInjectedSpecializationType();
687 return TemplateDeductionResult::Success;
694 ->template_arguments();
697 std::optional<NestedNameSpecifier *> NNS;
700 NNS = Elaborated->getQualifier();
702 UA = Injected->getInjectedSpecializationType();
713 return TemplateDeductionResult::Success;
720 ->template_arguments();
725 Result != TemplateDeductionResult::Success)
741 RA ? dyn_cast<ClassTemplateSpecializationDecl>(RA->getDecl()) :
nullptr;
745 return TemplateDeductionResult::NonDeducedMismatch;
751 *NNS,
false,
TemplateName(SA->getSpecializedTemplate()));
756 SA->getTemplateArgs().asArray(), Deduced);
757 Result != TemplateDeductionResult::Success)
762 SA->getTemplateArgs().asArray(), Info, Deduced,
770 case Type::TypeOfExpr:
772 case Type::DependentName:
774 case Type::PackIndexing:
775 case Type::UnresolvedUsing:
776 case Type::TemplateTypeParm:
780 case Type::ConstantArray:
781 case Type::IncompleteArray:
782 case Type::VariableArray:
783 case Type::DependentSizedArray:
785 cast<ArrayType>(
T)->getElementType().getTypePtr());
834class PackDeductionScope {
840 bool DeducePackIfNotAlreadyDeduced =
false)
841 : S(S), TemplateParams(TemplateParams), Deduced(Deduced), Info(Info),
842 DeducePackIfNotAlreadyDeduced(DeducePackIfNotAlreadyDeduced){
843 unsigned NumNamedPacks = addPacks(Pattern);
844 finishConstruction(NumNamedPacks);
851 : S(S), TemplateParams(TemplateParams), Deduced(Deduced), Info(Info) {
853 finishConstruction(1);
857 void addPack(
unsigned Index) {
860 DeducedFromEarlierParameter = !Deduced[Index].isNull();
862 Pack.Saved = Deduced[Index];
868 if (std::optional<unsigned> ExpandedPackExpansions =
870 FixedNumExpansions = ExpandedPackExpansions;
872 Packs.push_back(Pack);
878 llvm::SmallBitVector SawIndices(TemplateParams->size());
881 auto AddPack = [&](
unsigned Index) {
882 if (SawIndices[Index])
884 SawIndices[Index] =
true;
891 if (
auto *NTTP = dyn_cast<NonTypeTemplateParmDecl>(
892 TemplateParams->getParam(Index))) {
893 if (!NTTP->isExpandedParameterPack())
894 if (
auto *Expansion = dyn_cast<PackExpansionType>(NTTP->getType()))
895 ExtraDeductions.push_back(Expansion->getPattern());
904 for (
unsigned I = 0, N = Unexpanded.size(); I != N; ++I) {
905 unsigned Depth, Index;
907 if (Depth == Info.getDeducedDepth())
914 assert(!Packs.empty() &&
"Pack expansion without unexpanded packs?");
916 unsigned NumNamedPacks = Packs.size();
920 while (!ExtraDeductions.empty())
921 Collect(ExtraDeductions.pop_back_val());
923 return NumNamedPacks;
926 void finishConstruction(
unsigned NumNamedPacks) {
929 unsigned NumPartialPackArgs = 0;
930 std::pair<unsigned, unsigned> PartialPackDepthIndex(-1u, -1u);
932 if (
auto *Partial =
Scope->getPartiallySubstitutedPack(
933 &PartialPackArgs, &NumPartialPackArgs))
939 bool IsExpanded =
true;
940 for (
unsigned I = 0; I != NumNamedPacks; ++I) {
941 if (Packs[I].Index >= Info.getNumExplicitArgs()) {
943 IsPartiallyExpanded =
false;
946 if (PartialPackDepthIndex ==
947 std::make_pair(Info.getDeducedDepth(), Packs[I].Index)) {
948 IsPartiallyExpanded =
true;
956 if (IsPartiallyExpanded)
957 PackElements += NumPartialPackArgs;
958 else if (IsExpanded && FixedNumExpansions)
959 PackElements += *FixedNumExpansions;
961 for (
auto &Pack : Packs) {
962 if (Info.PendingDeducedPacks.size() > Pack.Index)
963 Pack.Outer = Info.PendingDeducedPacks[Pack.Index];
965 Info.PendingDeducedPacks.resize(Pack.Index + 1);
966 Info.PendingDeducedPacks[Pack.Index] = &Pack;
968 if (PartialPackDepthIndex ==
969 std::make_pair(Info.getDeducedDepth(), Pack.Index)) {
970 Pack.New.append(PartialPackArgs, PartialPackArgs + NumPartialPackArgs);
979 if (!IsPartiallyExpanded)
980 Deduced[Pack.Index] = Pack.New[PackElements];
986 ~PackDeductionScope() {
987 for (
auto &Pack : Packs)
988 Info.PendingDeducedPacks[Pack.Index] = Pack.Outer;
992 std::optional<unsigned> getSavedPackSizeIfAllEqual()
const {
993 unsigned PackSize = Packs[0].Saved.pack_size();
995 if (std::all_of(Packs.begin() + 1, Packs.end(), [&PackSize](
const auto &
P) {
996 return P.Saved.pack_size() == PackSize;
1004 bool isDeducedFromEarlierParameter()
const {
1005 return DeducedFromEarlierParameter;
1010 bool isPartiallyExpanded() {
return IsPartiallyExpanded; }
1015 bool hasFixedArity() {
return FixedNumExpansions.has_value(); }
1020 bool hasNextElement() {
1021 return !FixedNumExpansions || *FixedNumExpansions > PackElements;
1025 void nextPackElement() {
1029 for (
auto &Pack : Packs) {
1031 if (!Pack.New.empty() || !DeducedArg.
isNull()) {
1032 while (Pack.New.size() < PackElements)
1034 if (Pack.New.size() == PackElements)
1035 Pack.New.push_back(DeducedArg);
1037 Pack.New[PackElements] = DeducedArg;
1038 DeducedArg = Pack.New.size() > PackElements + 1
1039 ? Pack.New[PackElements + 1]
1052 for (
auto &Pack : Packs) {
1054 Deduced[Pack.Index] = Pack.Saved;
1069 Pack.New.resize(PackElements);
1073 if (Pack.New.empty()) {
1079 std::copy(Pack.New.begin(), Pack.New.end(), ArgumentPack);
1087 Pack.New[0].wasDeducedFromArrayBound());
1093 if (Pack.Outer->DeferredDeduction.isNull()) {
1096 Pack.Outer->DeferredDeduction = NewPack;
1099 Loc = &Pack.Outer->DeferredDeduction;
1101 Loc = &Deduced[Pack.Index];
1107 S.
Context, OldPack, NewPack, DeducePackIfNotAlreadyDeduced);
1109 Info.AggregateDeductionCandidateHasMismatchedArity =
1115 if (!Result.isNull() && !Pack.DeferredDeduction.isNull()) {
1117 NewPack = Pack.DeferredDeduction;
1121 NamedDecl *Param = TemplateParams->getParam(Pack.Index);
1122 if (Result.isNull()) {
1124 Info.FirstArg = OldPack;
1125 Info.SecondArg = NewPack;
1126 return TemplateDeductionResult::Inconsistent;
1132 if (*Expansions != PackElements) {
1134 Info.FirstArg = Result;
1135 return TemplateDeductionResult::IncompletePack;
1142 return TemplateDeductionResult::Success;
1150 unsigned PackElements = 0;
1151 bool IsPartiallyExpanded =
false;
1152 bool DeducePackIfNotAlreadyDeduced =
false;
1153 bool DeducedFromEarlierParameter =
false;
1155 std::optional<unsigned> FixedNumExpansions;
1194 const QualType *Params,
unsigned NumParams,
1195 const QualType *Args,
unsigned NumArgs,
1208 = dyn_cast<PackExpansionType>(Params[
ParamIdx]);
1213 if (ArgIdx >= NumArgs)
1214 return TemplateDeductionResult::MiscellaneousDeductionFailure;
1216 if (isa<PackExpansionType>(Args[ArgIdx])) {
1221 return TemplateDeductionResult::MiscellaneousDeductionFailure;
1225 S, TemplateParams, Params[
ParamIdx].getUnqualifiedType(),
1226 Args[ArgIdx].getUnqualifiedType(), Info, Deduced, TDF,
1229 Result != TemplateDeductionResult::Success)
1244 PackDeductionScope PackScope(S, TemplateParams, Deduced, Info, Pattern);
1248 if (
ParamIdx + 1 == NumParams || PackScope.hasFixedArity()) {
1249 for (; ArgIdx < NumArgs && PackScope.hasNextElement(); ++ArgIdx) {
1255 Result != TemplateDeductionResult::Success)
1258 PackScope.nextPackElement();
1279 if (NumExpansions && !PackScope.isPartiallyExpanded()) {
1280 for (
unsigned I = 0; I != *NumExpansions && ArgIdx < NumArgs;
1282 PackScope.nextPackElement();
1288 if (
auto Result = PackScope.finish();
1289 Result != TemplateDeductionResult::Success)
1300 isa<PackExpansionType>(Args[ArgIdx]))
1301 return TemplateDeductionResult::Success;
1304 if (ArgIdx < NumArgs)
1305 return TemplateDeductionResult::MiscellaneousDeductionFailure;
1307 return TemplateDeductionResult::Success;
1319 if (ParamQs == ArgQs)
1363 if (!Guide || !Guide->isImplicit())
1365 return Guide->getDeducedTemplate()->getTemplateParameters()->size();
1375 if (ParamRef->getPointeeType().getQualifiers())
1378 return TypeParm && TypeParm->
getIndex() >= FirstInnerIndex;
1436 assert(
T->
isRecordType() &&
"Base class that isn't a record?");
1438 ToVisit.push_back(
T);
1447 while (!ToVisit.empty()) {
1448 QualType NextT = ToVisit.pop_back_val();
1454 S, TemplateParams,
P, NextT, BaseInfo, DeducedCopy);
1460 Matches.insert({RD, DeducedCopy});
1471 if (Matches.size() > 1) {
1473 for (
const auto &Match : Matches)
1474 AddBases(Match.first);
1478 while (Matches.size() > 1 && !ToVisit.empty()) {
1479 const CXXRecordDecl *RD = ToVisit.pop_back_val()->getAsCXXRecordDecl();
1488 if (Matches.empty())
1490 if (Matches.size() > 1)
1493 std::swap(Matches.front().second, Deduced);
1529 if (
const auto *AExp = dyn_cast<PackExpansionType>(A))
1530 A = AExp->getPattern();
1611 TDF &= ~TDF_TopLevelParameterTypeList;
1614 P =
P->getPointeeType();
1631 unsigned Index = TTP->getIndex();
1646 Info.
Param = cast<TemplateTypeParmDecl>(TemplateParams->
getParam(Index));
1658 "saw template type parameter with wrong depth");
1660 "Unresolved overloaded function");
1680 Info.
Param = cast<TemplateTypeParmDecl>(TemplateParams->
getParam(Index));
1700 Info.
Param = cast<TemplateTypeParmDecl>(TemplateParams->
getParam(Index));
1745 if (!
P->isDependentType()) {
1761 switch (
P.getCanonicalType()->getTypeClass()) {
1763#define NON_CANONICAL_TYPE(Class, Base) \
1764 case Type::Class: llvm_unreachable("deducing non-canonical type: " #Class);
1765#define TYPE(Class, Base)
1766#include "clang/AST/TypeNodes.inc"
1768 case Type::TemplateTypeParm:
1769 case Type::SubstTemplateTypeParmPack:
1770 llvm_unreachable(
"Type nodes handled above");
1778 if (
P->isDependentType())
1782 case Type::VariableArray:
1784 case Type::FunctionNoProto:
1787 case Type::ObjCObject:
1788 case Type::ObjCInterface:
1789 case Type::ObjCObjectPointer:
1799 case Type::Complex: {
1804 S, TemplateParams, CP->getElementType(), CA->getElementType(), Info,
1809 case Type::Atomic: {
1814 S, TemplateParams, PA->getValueType(), AA->getValueType(), Info,
1819 case Type::Pointer: {
1830 PointeeType, Info, Deduced,
1835 case Type::LValueReference: {
1842 S, TemplateParams, RP->getPointeeType(), RA->getPointeeType(), Info,
1847 case Type::RValueReference: {
1854 S, TemplateParams, RP->getPointeeType(), RA->getPointeeType(), Info,
1859 case Type::IncompleteArray: {
1865 assert(IAP &&
"Template parameter not of incomplete array type");
1868 S, TemplateParams, IAP->getElementType(), IAA->getElementType(), Info,
1873 case Type::ConstantArray: {
1877 if (!CAA || CAA->getSize() != CAP->getSize())
1881 S, TemplateParams, CAP->getElementType(), CAA->getElementType(), Info,
1886 case Type::DependentSizedArray: {
1895 S, TemplateParams, DAP->getElementType(), AA->getElementType(),
1909 "saw non-type template parameter with wrong depth");
1910 if (
const auto *CAA = dyn_cast<ConstantArrayType>(AA)) {
1911 llvm::APSInt Size(CAA->getSize());
1914 true, Info, Deduced);
1916 if (
const auto *DAA = dyn_cast<DependentSizedArrayType>(AA))
1917 if (DAA->getSizeExpr())
1919 S, TemplateParams, NTTP, DAA->getSizeExpr(), Info, Deduced);
1928 case Type::FunctionProto: {
1934 if (FPP->getMethodQuals() != FPA->getMethodQuals() ||
1935 FPP->getRefQualifier() != FPA->getRefQualifier() ||
1936 FPP->isVariadic() != FPA->isVariadic())
1941 S, TemplateParams, FPP->getReturnType(), FPA->getReturnType(),
1950 S, TemplateParams, FPP->param_type_begin(), FPP->getNumParams(),
1951 FPA->param_type_begin(), FPA->getNumParams(), Info, Deduced,
1962 Expr *NoexceptExpr = FPP->getNoexceptExpr();
1967 "saw non-type template parameter with wrong depth");
1969 llvm::APSInt Noexcept(1);
1970 switch (FPA->canThrow()) {
1980 true, Info, Deduced);
1983 if (
Expr *ArgNoexceptExpr = FPA->getNoexceptExpr())
1985 S, TemplateParams, NTTP, ArgNoexceptExpr, Info, Deduced);
1998 case Type::InjectedClassName:
2007 case Type::TemplateSpecialization: {
2033 Deduced = DeducedOrig;
2051 case Type::MemberPointer: {
2068 S, TemplateParams, PPT, APT, Info, Deduced, SubTDF);
2072 S, TemplateParams,
QualType(MPP->getClass(), 0),
2073 QualType(MPA->getClass(), 0), Info, Deduced, SubTDF);
2081 case Type::BlockPointer: {
2087 S, TemplateParams, BPP->getPointeeType(), BPA->getPointeeType(), Info,
2094 case Type::ExtVector: {
2099 if (VP->getNumElements() != VA->getNumElements())
2101 ElementType = VA->getElementType();
2106 ElementType = VA->getElementType();
2112 S, TemplateParams, VP->getElementType(), ElementType, Info, Deduced,
2116 case Type::DependentVector: {
2122 S, TemplateParams, VP->getElementType(), VA->getElementType(),
2123 Info, Deduced, TDF);
2134 ArgSize = VA->getNumElements();
2146 S, TemplateParams, VP->getElementType(), VA->getElementType(),
2147 Info, Deduced, TDF);
2158 VA->getSizeExpr(), Info, Deduced);
2167 case Type::DependentSizedExtVector: {
2173 S, TemplateParams, VP->getElementType(), VA->getElementType(),
2174 Info, Deduced, TDF);
2185 ArgSize = VA->getNumElements();
2197 S, TemplateParams, VP->getElementType(), VA->getElementType(),
2198 Info, Deduced, TDF);
2209 VA->getSizeExpr(), Info, Deduced);
2219 case Type::ConstantMatrix: {
2226 if (MP->getNumRows() != MA->getNumRows() ||
2227 MP->getNumColumns() != MA->getNumColumns()) {
2232 S, TemplateParams, MP->getElementType(), MA->getElementType(), Info,
2236 case Type::DependentSizedMatrix: {
2245 Info, Deduced, TDF);
2250 auto DeduceMatrixArg =
2251 [&S, &Info, &Deduced, &TemplateParams](
2255 const auto *ACM = dyn_cast<ConstantMatrixType>(A);
2256 const auto *ADM = dyn_cast<DependentSizedMatrixType>(A);
2257 if (!ParamExpr->isValueDependent()) {
2258 std::optional<llvm::APSInt> ParamConst =
2259 ParamExpr->getIntegerConstantExpr(S.
Context);
2264 if ((ACM->*GetArgDimension)() == *ParamConst)
2269 Expr *ArgExpr = (ADM->*GetArgDimensionExpr)();
2270 if (std::optional<llvm::APSInt> ArgConst =
2272 if (*ArgConst == *ParamConst)
2283 llvm::APSInt ArgConst(
2285 ArgConst = (ACM->*GetArgDimension)();
2288 true, Info, Deduced);
2292 (ADM->*GetArgDimensionExpr)(),
2296 if (
auto Result = DeduceMatrixArg(MP->getRowExpr(), MA,
2302 return DeduceMatrixArg(MP->getColumnExpr(), MA,
2310 case Type::DependentAddressSpace: {
2316 S, TemplateParams, ASP->getPointeeType(), ASA->getPointeeType(),
2317 Info, Deduced, TDF);
2328 S, TemplateParams, NTTP, ASA->getAddrSpaceExpr(), Info, Deduced);
2338 S, TemplateParams, ASP->getPointeeType(),
2351 true, Info, Deduced);
2356 case Type::DependentBitInt: {
2360 if (IP->isUnsigned() != IA->isUnsigned())
2369 ArgSize = IA->getNumBits();
2377 if (IP->isUnsigned() != IA->isUnsigned())
2385 case Type::TypeOfExpr:
2387 case Type::DependentName:
2388 case Type::UnresolvedUsing:
2389 case Type::Decltype:
2390 case Type::UnaryTransform:
2391 case Type::DeducedTemplateSpecialization:
2392 case Type::DependentTemplateSpecialization:
2393 case Type::PackExpansion:
2395 case Type::ArrayParameter:
2399 case Type::PackIndexing: {
2409 llvm_unreachable(
"Invalid Type Class!");
2423 switch (
P.getKind()) {
2425 llvm_unreachable(
"Null template argument in parameter list");
2430 S, TemplateParams,
P.getAsType(), A.
getAsType(), Info, Deduced, 0);
2445 llvm_unreachable(
"caller should handle pack expansions");
2512 llvm_unreachable(
"Unknown template argument kind");
2518 llvm_unreachable(
"Argument packs should be expanded by the caller!");
2521 llvm_unreachable(
"Invalid TemplateArgument Kind!");
2534 if (ArgIdx == Args.size())
2541 assert(ArgIdx == Args.size() - 1 &&
"Pack not at the end of argument list?");
2544 return ArgIdx < Args.size();
2550 bool FoundPackExpansion =
false;
2551 for (
const auto &A : Args) {
2552 if (FoundPackExpansion)
2560 if (A.isPackExpansion())
2561 FoundPackExpansion =
true;
2574 if (
PackFold == PackFold::ArgumentToParameter)
2590 if (!
P.isPackExpansion()) {
2595 return NumberOfArgumentsMustMatch
2602 if (As[ArgIdx].isPackExpansion())
2607 if (
PackFold == PackFold::ArgumentToParameter)
2629 PackDeductionScope PackScope(S, TemplateParams, Deduced, Info, Pattern);
2635 PackScope.hasNextElement();
2638 if (
PackFold == PackFold::ArgumentToParameter)
2646 PackScope.nextPackElement();
2651 if (
auto Result = PackScope.finish();
2663 bool NumberOfArgumentsMustMatch) {
2664 return ::DeduceTemplateArguments(*
this, TemplateParams, Ps, As, Info, Deduced,
2665 NumberOfArgumentsMustMatch);
2673 bool PackExpansionMatchesPack =
false) {
2676 if (PackExpansionMatchesPack &&
X.isPackExpansion() && !Y.
isPackExpansion())
2677 X =
X.getPackExpansionPattern();
2682 switch (
X.getKind()) {
2684 llvm_unreachable(
"Comparing NULL template argument");
2707 return X.structurallyEquals(Y);
2710 llvm::FoldingSetNodeID XID, YID;
2711 X.getAsExpr()->Profile(XID, Context,
true);
2717 unsigned PackIterationSize =
X.pack_size();
2726 bool XHasMoreArg =
X.pack_size() > Y.
pack_size();
2727 if (!(XHasMoreArg &&
X.pack_elements().back().isPackExpansion()) &&
2728 !(!XHasMoreArg && Y.
pack_elements().back().isPackExpansion()))
2737 for (
unsigned i = 0; i < PackIterationSize; ++i)
2739 PackExpansionMatchesPack))
2745 llvm_unreachable(
"Invalid TemplateArgument Kind!");
2754 llvm_unreachable(
"Can't get a NULL template argument here");
2789 Builder.MakeTrivial(
Context, DTN->getQualifier(),
Loc);
2792 Builder.MakeTrivial(
Context, QTN->getQualifier(),
Loc);
2809 llvm_unreachable(
"Invalid TemplateArgument Kind!");
2827 unsigned ArgumentPackIndex) {
2849 CanonicalPackedArgsBuilder;
2857 "deduced nested pack");
2864 diag::err_template_arg_deduced_incomplete_pack)
2868 if (ConvertArg(InnerArg, SugaredPackedArgsBuilder.size()))
2872 SugaredPackedArgsBuilder.push_back(SugaredOutput.pop_back_val());
2873 CanonicalPackedArgsBuilder.push_back(CanonicalOutput.pop_back_val());
2878 if (SugaredPackedArgsBuilder.empty()) {
2883 if (
auto *NTTP = dyn_cast<NonTypeTemplateParmDecl>(Param)) {
2885 NTTP, SugaredOutput,
2888 S.
SubstType(NTTP->getType(), Args, NTTP->getLocation(),
2889 NTTP->getDeclName()).isNull())
2891 }
else if (
auto *TTP = dyn_cast<TemplateTemplateParmDecl>(Param)) {
2902 SugaredOutput.push_back(
2905 S.
Context, CanonicalPackedArgsBuilder));
2909 return ConvertArg(Arg, 0);
2915template <
typename TemplateDeclT>
2917 Sema &S, TemplateDeclT *Template,
bool IsDeduced,
2923 unsigned NumAlreadyConverted = 0,
bool PartialOverloading =
false) {
2926 for (
unsigned I = 0, N = TemplateParams->
size(); I != N; ++I) {
2935 PackDeductionScope(S, TemplateParams, Deduced, Info, I).finish();
2940 if (!Deduced[I].isNull()) {
2941 if (I < NumAlreadyConverted) {
2946 CurrentInstantiationScope->getPartiallySubstitutedPack() == Param) {
2949 CurrentInstantiationScope->ResetPartiallySubstitutedPack();
2956 SugaredBuilder.push_back(Deduced[I]);
2957 CanonicalBuilder.push_back(
2966 IsDeduced, SugaredBuilder,
2967 CanonicalBuilder)) {
2980 bool HasDefaultArg =
false;
2983 assert(isa<ClassTemplatePartialSpecializationDecl>(Template) ||
2984 isa<VarTemplatePartialSpecializationDecl>(Template));
2993 if (Rec->isLambda())
2994 if (
auto *Method = dyn_cast<CXXMethodDecl>(Rec->getDeclContext())) {
2996 ThisTypeQuals = Method->getMethodQualifiers();
3004 SugaredBuilder, CanonicalBuilder, HasDefaultArg);
3013 if (PartialOverloading)
break;
3038 if (
auto *DC = dyn_cast<DeclContext>(
D))
3044 static constexpr bool value =
false;
3048 static constexpr bool value =
true;
3052 static constexpr bool value =
true;
3054template <
typename TemplateDeclT>
3069template <
typename TemplateDeclT>
3076 Template->getAssociatedConstraints(AssociatedConstraints);
3078 std::optional<ArrayRef<TemplateArgument>> Innermost;
3082 Innermost = CanonicalDeducedArgs;
3085 Template, Template->getDeclContext(),
false, Innermost,
3109template <
typename T>
3110static std::enable_if_t<IsPartialSpecialization<T>::value,
3113 Sema &S,
T *Partial,
bool IsPartialOrdering,
3129 S, Partial, IsPartialOrdering, Deduced, Info, SugaredBuilder,
3140 Info.
reset(SugaredDeducedArgumentList, CanonicalDeducedArgumentList);
3148 auto *Template = Partial->getSpecializedTemplate();
3150 Partial->getTemplateArgsAsWritten();
3161 if (
ParamIdx >= Partial->getTemplateParameters()->size())
3162 ParamIdx = Partial->getTemplateParameters()->size() - 1;
3165 Partial->getTemplateParameters()->getParam(
ParamIdx));
3167 Info.
FirstArg = (*PartialTemplArgInfo)[ArgIdx].getArgument();
3173 CanonicalConvertedInstArgs;
3175 Template, Partial->getLocation(), InstArgs,
false,
3176 SugaredConvertedInstArgs, CanonicalConvertedInstArgs,
3183 for (
unsigned I = 0,
E = TemplateParams->
size(); I !=
E; ++I) {
3186 IsPartialOrdering)) {
3198 CanonicalBuilder, Info);
3226 SugaredBuilder, CanonicalBuilder,
3234 for (
unsigned I = 0,
E = TemplateParams->
size(); I !=
E; ++I) {
3249 CanonicalBuilder, Info);
3274 S, TD,
false, Deduced, Info, SugaredBuilder,
3283 CanonicalBuilder, Info);
3293template <
typename T>
3294static std::enable_if_t<IsPartialSpecialization<T>::value,
3299 if (Partial->isInvalidDecl())
3318 Deduced.resize(Partial->getTemplateParameters()->size());
3320 S, Partial->getTemplateParameters(),
3321 Partial->getTemplateArgs().asArray(), TemplateArgs, Info, Deduced,
3337 Result = ::FinishTemplateArgumentDeduction(S, Partial,
3339 TemplateArgs, Deduced, Info);
3348 return ::DeduceTemplateArguments(*
this, Partial, TemplateArgs, Info);
3354 return ::DeduceTemplateArguments(*
this, Partial, TemplateArgs, Info);
3364 if (
const auto *CTD = dyn_cast<ClassTemplateDecl>(TD)) {
3367 }
else if (
const auto *
AliasTemplate = dyn_cast<TypeAliasTemplateDecl>(TD)) {
3368 PType =
AliasTemplate->getTemplatedDecl()->getUnderlyingType();
3370 assert(
false &&
"Expected a class or alias template");
3389 return DeducedResult;
3402 Result = ::FinishTemplateArgumentDeduction(*this, TD, Deduced, Info);
3411 return Spec->getTemplateName().getAsTemplateDecl() !=
nullptr;
3437 if (ExplicitTemplateArgs.
size() == 0) {
3441 ParamTypes.push_back(
P->getType());
3471 ExplicitTemplateArgs,
true, SugaredBuilder,
3475 unsigned Index = SugaredBuilder.size();
3476 if (Index >= TemplateParams->
size())
3489 CanonicalExplicitArgumentList);
3501 unsigned PartiallySubstitutedPackIndex = -1u;
3502 if (!SugaredBuilder.empty()) {
3505 auto *Param = TemplateParams->
getParam(SugaredBuilder.size() - 1);
3509 if (!Expansions || Arg.
pack_size() < *Expansions) {
3510 PartiallySubstitutedPackIndex = SugaredBuilder.size() - 1;
3519 assert(Proto &&
"Function template does not have a prototype?");
3527 SugaredExplicitArgumentList->
asArray(),
3537 nullptr, ExtParamInfos))
3554 ThisTypeQuals = Method->getMethodQualifiers();
3568 Diag(
Function->getLocation(), diag::err_kern_type_not_void_return)
3579 nullptr, ExtParamInfos))
3603 Deduced.reserve(TemplateParams->
size());
3604 for (
unsigned I = 0, N = SugaredExplicitArgumentList->
size(); I != N; ++I) {
3606 if (I == PartiallySubstitutedPackIndex)
3609 Deduced.push_back(Arg);
3678 if (AQuals == DeducedAQuals) {
3696 bool ObjCLifetimeConversion =
false;
3700 ObjCLifetimeConversion) ||
3746 if (PD->isParameterPack()) {
3747 unsigned NumExpansions =
3749 if (Idx + NumExpansions >
ParamIdx)
3751 Idx += NumExpansions;
3759 llvm_unreachable(
"parameter index would not be produced from template");
3771 return isa<CXXConstructorDecl>(
D)
3772 ? cast<CXXConstructorDecl>(
D)->getExplicitSpecifier()
3773 : cast<CXXConversionDecl>(
D)->getExplicitSpecifier();
3776 isa<CXXConstructorDecl>(
D)
3777 ? cast<CXXConstructorDecl>(
D)->setExplicitSpecifier(ES)
3778 : cast<CXXConversionDecl>(
D)->setExplicitSpecifier(ES);
3789 S, Info.
getLocation(), FunctionTemplate, DeducedArgs,
3810 bool PartialOverloading, llvm::function_ref<
bool()> CheckNonDependent) {
3834 NumExplicitlySpecified, PartialOverloading);
3847 if (CheckNonDependent())
3855 Info.
reset(SugaredDeducedArgumentList, CanonicalDeducedArgumentList);
3893 CanonicalDeducedArgumentList &&
3913 if (!PartialOverloading ||
3914 (CanonicalBuilder.size() ==
3931 if (isa<CXXConstructorDecl, CXXConversionDecl>(
Specialization)) {
3940 if (OriginalCallArgs) {
3945 llvm::SmallDenseMap<std::pair<unsigned, QualType>,
QualType> DeducedATypes;
3946 for (
unsigned I = 0, N = OriginalCallArgs->size(); I != N; ++I) {
3950 unsigned ExplicitOffset =
3970 if (CacheEntry.
isNull()) {
3979 DeducedA = CacheEntry;
3994 SuppressedDiagnosticsMap::iterator
4009 if (S.
getLangOpts().CPlusPlus14 && Fn->getReturnType()->isUndeducedType() &&
4014 if (Method->isImplicitObjectMemberFunction()) {
4035 bool ParamWasReference,
4044 if (ParamWasReference)
4061 nullptr, FailedTSC))
4102 if (ArgType.
isNull())
continue;
4122 Deduced(TemplateParams->
size());
4125 S, TemplateParams, ParamType, ArgType, Info, Deduced, TDF);
4163 assert(Arg &&
"expected a non-null arg expression");
4165 ParamRefType !=
nullptr, FailedTSC);
4173 assert(Arg &&
"expected a non-null arg expression");
4228 (isa<PointerType>(ParamType) &&
4247 bool DecomposedParam,
unsigned ArgIdx,
unsigned TDF,
4272 ElTy = ArrTy->getElementType();
4282 if (isa<DesignatedInitExpr>(
E))
4289 S, TemplateParams, 0, ElTy,
E->
getType(),
4291 OriginalCallArgs,
true, ArgIdx, TDF);
4299 if (
auto *DependentArrTy = dyn_cast_or_null<DependentSizedArrayType>(ArrTy)) {
4310 S, TemplateParams, NTTP, llvm::APSInt(Size),
T,
4311 true, Info, Deduced);
4329 bool DecomposedParam,
unsigned ArgIdx,
unsigned TDF,
4332 QualType OrigParamType = ParamType;
4337 S, TemplateParams, FirstInnerIndex, ParamType, ArgType,
4338 ArgClassification, Arg, TDF, FailedTSC))
4342 if (
InitListExpr *ILE = dyn_cast_if_present<InitListExpr>(Arg))
4344 Deduced, OriginalCallArgs, ArgIdx, TDF);
4352 OriginalCallArgs.push_back(
4355 ArgType, Info, Deduced, TDF);
4362 bool PartialOverloading,
bool AggregateDeductionCandidate,
4369 unsigned NumParams =
Function->getNumParams();
4370 bool HasExplicitObject =
false;
4371 int ExplicitObjectOffset = 0;
4372 if (
Function->hasCXXExplicitFunctionObjectParameter()) {
4373 HasExplicitObject =
true;
4374 ExplicitObjectOffset = 1;
4383 if (Args.size() <
Function->getMinRequiredExplicitArguments() &&
4384 !PartialOverloading)
4387 PartialOverloading)) {
4389 if (Proto->isTemplateVariadic())
4391 else if (!Proto->isVariadic())
4402 unsigned NumExplicitlySpecified = 0;
4403 if (ExplicitTemplateArgs) {
4406 Result = SubstituteExplicitTemplateArguments(
4407 FunctionTemplate, *ExplicitTemplateArgs, Deduced, ParamTypes, nullptr,
4413 NumExplicitlySpecified = Deduced.size();
4416 for (
unsigned I = 0; I != NumParams; ++I)
4417 ParamTypes.push_back(
Function->getParamDecl(I)->getType());
4423 auto DeduceCallArgument = [&](
QualType ParamType,
unsigned ArgIdx,
4424 bool ExplicitObjectArgument) {
4432 if (ExplicitObjectArgument) {
4435 *
this, TemplateParams, FirstInnerIndex, ParamType, ObjectType,
4436 ObjectClassification,
4437 nullptr, Info, Deduced, OriginalCallArgs,
4443 *
this, TemplateParams, FirstInnerIndex, ParamType,
4444 Args[ArgIdx]->getType(), Args[ArgIdx]->Classify(
getASTContext()),
4445 Args[ArgIdx], Info, Deduced, OriginalCallArgs,
false,
4450 Deduced.resize(TemplateParams->
size());
4452 for (
unsigned ParamIdx = 0, NumParamTypes = ParamTypes.size(), ArgIdx = 0;
4457 dyn_cast<PackExpansionType>(ParamType);
4458 if (!ParamExpansion) {
4460 if (ArgIdx >= Args.size() && !(HasExplicitObject &&
ParamIdx == 0))
4463 ParamTypesForArgChecking.push_back(ParamType);
4465 if (
ParamIdx == 0 && HasExplicitObject) {
4469 if (
auto Result = DeduceCallArgument(ParamType, 0,
4476 if (
auto Result = DeduceCallArgument(ParamType, ArgIdx++,
4484 bool IsTrailingPack =
ParamIdx + 1 == NumParamTypes;
4487 PackDeductionScope PackScope(*
this, TemplateParams, Deduced, Info,
4489 AggregateDeductionCandidate && IsTrailingPack);
4507 if (IsTrailingPack || PackScope.hasFixedArity()) {
4508 for (; ArgIdx < Args.size() && PackScope.hasNextElement();
4509 PackScope.nextPackElement(), ++ArgIdx) {
4510 ParamTypesForArgChecking.push_back(ParamPattern);
4511 if (
auto Result = DeduceCallArgument(ParamPattern, ArgIdx,
4520 std::optional<unsigned> NumExpansions =
4522 if (NumExpansions && !PackScope.isPartiallyExpanded()) {
4523 for (
unsigned I = 0; I != *NumExpansions && ArgIdx < Args.size();
4525 ParamTypesForArgChecking.push_back(ParamPattern);
4528 PackScope.nextPackElement();
4530 }
else if (!IsTrailingPack && !PackScope.isPartiallyExpanded() &&
4531 PackScope.isDeducedFromEarlierParameter()) {
4544 std::optional<unsigned> ArgPosAfterSubstitution =
4545 PackScope.getSavedPackSizeIfAllEqual();
4546 if (!ArgPosAfterSubstitution)
4549 unsigned PackArgEnd = ArgIdx + *ArgPosAfterSubstitution;
4550 for (; ArgIdx < PackArgEnd && ArgIdx < Args.size(); ArgIdx++) {
4551 ParamTypesForArgChecking.push_back(ParamPattern);
4553 DeduceCallArgument(ParamPattern, ArgIdx,
4558 PackScope.nextPackElement();
4565 if (
auto Result = PackScope.finish();
4576 Result = FinishTemplateArgumentDeduction(
4577 FunctionTemplate, Deduced, NumExplicitlySpecified, Specialization, Info,
4578 &OriginalCallArgs, PartialOverloading, [&, CallingCtx]() {
4579 ContextRAII SavedContext(*this, CallingCtx);
4580 return CheckNonDependent(ParamTypesForArgChecking);
4588 bool AdjustExceptionSpec) {
4589 if (ArgFunctionType.
isNull())
4590 return ArgFunctionType;
4595 bool Rebuild =
false;
4598 if (EPI.ExtInfo.getCC() != CC) {
4599 EPI.
ExtInfo = EPI.ExtInfo.withCallingConv(CC);
4603 bool NoReturn = FunctionTypeP->getNoReturnAttr();
4604 if (EPI.ExtInfo.getNoReturn() != NoReturn) {
4605 EPI.ExtInfo = EPI.ExtInfo.withNoReturn(NoReturn);
4609 if (AdjustExceptionSpec && (FunctionTypeP->hasExceptionSpec() ||
4611 EPI.ExceptionSpec = FunctionTypeP->getExtProtoInfo().ExceptionSpec;
4616 return ArgFunctionType;
4626 bool IsAddressOfFunction) {
4638 unsigned NumExplicitlySpecified = 0;
4640 if (ExplicitTemplateArgs) {
4643 Result = SubstituteExplicitTemplateArguments(
4644 FunctionTemplate, *ExplicitTemplateArgs, Deduced, ParamTypes,
4645 &FunctionType, Info);
4650 NumExplicitlySpecified = Deduced.size();
4656 if (!IsAddressOfFunction)
4665 Deduced.resize(TemplateParams->
size());
4669 bool HasDeducedReturnType =
false;
4671 Function->getReturnType()->getContainedAutoType()) {
4673 HasDeducedReturnType =
true;
4681 *
this, TemplateParams,
FunctionType, ArgFunctionType, Info, Deduced,
4689 Result = FinishTemplateArgumentDeduction(FunctionTemplate, Deduced,
4690 NumExplicitlySpecified,
4691 Specialization, Info);
4698 if (HasDeducedReturnType && IsAddressOfFunction &&
4719 if (!IsAddressOfFunction) {
4725 if (HasDeducedReturnType) {
4734 if (!ArgFunctionType.
isNull()) {
4736 SpecializationType, ArgFunctionType)
4738 SpecializationType, ArgFunctionType)) {
4759 bool IsReferenceP =
P->isReferenceType();
4766 P = PRef->getPointeeType();
4776 if (!IsReferenceP) {
4778 P =
P.getUnqualifiedType();
4785 assert(!A->
isReferenceType() &&
"Reference types were handled above");
4790 if (
P->isArrayType())
4795 else if (
P->isFunctionType())
4800 P =
P.getUnqualifiedType();
4822 Deduced.resize(TemplateParams->
size());
4851 ParamType, ObjectType, ObjectClassification,
4852 nullptr, Info, Deduced, OriginalCallArgs,
4859 *
this, TemplateParams,
P, A, Info, Deduced, TDF);
4869 Result = FinishTemplateArgumentDeduction(ConversionTemplate, Deduced, 0,
4870 ConversionSpecialized, Info,
4873 Specialization = cast_or_null<CXXConversionDecl>(ConversionSpecialized);
4882 bool IsAddressOfFunction) {
4885 IsAddressOfFunction);
4889 struct DependentAuto {
bool IsPack; };
4893 class SubstituteDeducedTypeTransform :
4896 bool ReplacementIsPack;
4901 SubstituteDeducedTypeTransform(
Sema &SemaRef, DependentAuto DA)
4903 ReplacementIsPack(DA.IsPack), UseTypeSugar(
true) {}
4905 SubstituteDeducedTypeTransform(
Sema &SemaRef,
QualType Replacement,
4906 bool UseTypeSugar =
true)
4908 Replacement(Replacement), ReplacementIsPack(
false),
4909 UseTypeSugar(UseTypeSugar) {}
4912 assert(isa<TemplateTypeParmType>(Replacement) &&
4913 "unexpected unsugared replacement kind");
4931 return TransformDesugared(TLB, TL);
4933 QualType Result = SemaRef.Context.getAutoType(
4942 QualType TransformDeducedTemplateSpecializationType(
4945 return TransformDesugared(TLB, TL);
4947 QualType Result = SemaRef.Context.getDeducedTemplateSpecializationType(
4949 Replacement, Replacement.isNull());
4967 return inherited::TransformExceptionSpec(
Loc, ESI, Exceptions, Changed);
4975 return TransformType(TLB, TL);
4991 Deduced,
TypeLoc.getNameLoc())));
4992 for (
unsigned I = 0,
C =
TypeLoc.getNumArgs(); I !=
C; ++I)
4998 SugaredConverted, CanonicalConverted))
5014 S.
getASTContext(), Concept->getDeclContext(), Concept->getLocation(),
5015 CanonicalConverted));
5022 llvm::raw_string_ostream OS(Buf);
5023 OS <<
"'" << Concept->getName();
5024 if (
TypeLoc.hasExplicitTemplateArgs()) {
5027 Type.getTypeConstraintConcept()->getTemplateParameters());
5032 diag::err_placeholder_constraints_not_satisfied)
5043 bool IgnoreConstraints,
5046 if (
Init->containsErrors())
5059 DependentAuto DependentResult = {
5062 if (!DependentDeduction &&
5064 Init->containsUnexpandedParameterPack())) {
5065 Result = SubstituteDeducedTypeTransform(*
this, DependentResult).Apply(
Type);
5066 assert(!
Result.isNull() &&
"substituting DependentTy can't fail");
5071 auto *String = dyn_cast<StringLiteral>(
Init);
5073 Diag(
Type.getBeginLoc(), diag::ext_c23_auto_non_plain_identifier);
5075 Result = SubstituteDeducedTypeTransform(*
this, DependentResult).Apply(TL);
5076 assert(!
Result.isNull() &&
"substituting DependentTy can't fail");
5082 Diag(
Type.getBeginLoc(), diag::ext_c23_auto_non_plain_identifier);
5085 auto *InitList = dyn_cast<InitListExpr>(
Init);
5087 Diag(
Init->getBeginLoc(), diag::err_auto_init_list_from_c)
5099 if (
Init->isTypeDependent()) {
5101 SubstituteDeducedTypeTransform(*
this, DependentResult).Apply(
Type);
5102 assert(!
Result.isNull() &&
"substituting DependentTy can't fail");
5114 Diag(
Init->getBeginLoc(), diag::err_decltype_auto_initializer_list);
5127 nullptr,
false,
false,
false);
5141 for (
Expr *
Init : InitList->inits()) {
5144 if (isa<DesignatedInitExpr>(
Init))
5147 *
this, TemplateParamsSt.get(), 0, TemplArg,
Init->getType(),
5149 OriginalCallArgs,
true,
5155 <<
Init->getSourceRange();
5158 return DeductionFailed(TDK);
5163 DeducedFromInitRange =
Init->getSourceRange();
5167 Diag(
Loc, diag::err_auto_bitfield);
5171 SubstituteDeducedTypeTransform(*
this, TemplArg).Apply(
Type);
5172 assert(!FuncParam.
isNull() &&
5173 "substituting template parameter for 'auto' failed");
5175 *
this, TemplateParamsSt.get(), 0, FuncParam,
Init->getType(),
5177 OriginalCallArgs,
false, 0, 0,
5180 return DeductionFailed(TDK);
5217 assert((
bool)InitList == OriginalArg.DecomposedParam &&
5218 "decomposed non-init-list in auto deduction?");
5223 return DeductionFailed(TDK);
5233 return SubstituteDeducedTypeTransform(*
this, TypeToReplaceAuto)
5234 .TransformType(TypeWithAuto);
5240 return SubstituteDeducedTypeTransform(*
this, TypeToReplaceAuto)
5241 .TransformType(TypeWithAuto);
5245 return SubstituteDeducedTypeTransform(*
this, DependentAuto{
false})
5246 .TransformType(TypeWithAuto);
5251 return SubstituteDeducedTypeTransform(*
this, DependentAuto{
false})
5252 .TransformType(TypeWithAuto);
5257 return SubstituteDeducedTypeTransform(*
this, TypeToReplaceAuto,
5259 .TransformType(TypeWithAuto);
5264 return SubstituteDeducedTypeTransform(*
this, TypeToReplaceAuto,
5266 .TransformType(TypeWithAuto);
5271 if (isa<InitListExpr>(
Init))
5274 ? diag::err_init_capture_deduction_failure_from_init_list
5275 : diag::err_auto_var_deduction_failure_from_init_list)
5279 VDecl->
isInitCapture() ? diag::err_init_capture_deduction_failure
5280 : diag::err_auto_var_deduction_failure)
5282 <<
Init->getSourceRange();
5314 "failed to deduce lambda return type");
5341 Diag(
Loc, diag::err_auto_fn_used_before_defined) << FD;
5345 return StillUndeduced;
5389 "expected a member function with no explicit object parameter");
5414 assert(Proto1 && Proto2 &&
"Function templates must have prototypes");
5417 Deduced.resize(TemplateParams->
size());
5426 Args1.data(), Args1.size(), Info, Deduced,
5437 S, TemplateParams, Proto2->getReturnType(), Proto1->
getReturnType(),
5447 S, TemplateParams, FD2->
getType(), FD1->
getType(), Info, Deduced,
5460 unsigned ArgIdx = 0, NumArgs = Deduced.size();
5461 for (; ArgIdx != NumArgs; ++ArgIdx)
5462 if (Deduced[ArgIdx].isNull())
5469 if (ArgIdx == NumArgs) {
5476 llvm::SmallBitVector UsedParameters(TemplateParams->
size());
5479 for (
unsigned I = 0, N = Args2.size(); I != N; ++I)
5481 TemplateParams->
getDepth(), UsedParameters);
5487 TemplateParams->
getDepth(), UsedParameters);
5513 false, TemplateParams->
getDepth(), UsedParameters);
5517 for (; ArgIdx != NumArgs; ++ArgIdx)
5520 if (Deduced[ArgIdx].isNull() && UsedParameters[ArgIdx])
5534 bool ShouldConvert1 =
false;
5535 bool ShouldConvert2 =
false;
5546 const CXXMethodDecl *Method1 = dyn_cast<CXXMethodDecl>(FD1);
5547 const CXXMethodDecl *Method2 = dyn_cast<CXXMethodDecl>(FD2);
5557 ShouldConvert1 = Method1 && !Method1->isExplicitObjectMemberFunction();
5559 if (ShouldConvert1) {
5563 : Proto2->param_type_begin()[0]->isRValueReferenceType();
5567 Args1.push_back(Obj1Ty);
5569 if (ShouldConvert2) {
5572 ? Method1->getRefQualifier() ==
RQ_RValue
5577 Args2.push_back(Obj2Ty);
5579 size_t NumComparedArguments = NumCallArguments1;
5583 ++NumComparedArguments;
5587 Args2.insert(Args2.end(), Proto2->param_type_begin(),
5588 Proto2->param_type_end());
5593 Args1.resize(std::min(Args1.size(), NumComparedArguments));
5594 Args2.resize(std::min(Args2.size(), NumComparedArguments));
5597 std::reverse(Args2.begin(), Args2.end());
5606 if (Better1 != Better2)
5607 return Better1 ? FT1 : FT2;
5609 if (!Better1 && !Better2)
5618 Param1.reserve(FD1->
param_size() + ShouldConvert1);
5620 Param1.push_back(Obj1Ty);
5622 Param1.push_back(
P->getType());
5625 Param2.reserve(FD2->
param_size() + ShouldConvert2);
5627 Param2.push_back(Obj2Ty);
5629 Param2.push_back(
P->getType());
5631 unsigned NumParams1 = Param1.size();
5632 unsigned NumParams2 = Param2.size();
5638 if (Variadic1 != Variadic2) {
5639 if (Variadic1 && NumParams1 > NumParams2)
5641 if (Variadic2 && NumParams2 > NumParams1)
5647 for (
int i = 0, e = std::min(NumParams1, NumParams2); i < e; ++i) {
5648 QualType T1 = Param1[i].getCanonicalType();
5649 QualType T2 = Param2[i].getCanonicalType();
5650 auto *TST1 = dyn_cast<TemplateSpecializationType>(T1);
5651 auto *TST2 = dyn_cast<TemplateSpecializationType>(T2);
5656 assert(TST1->template_arguments().size() ==
5657 TST2->template_arguments().size());
5662 bool IsPackExpansion1 =
5664 bool IsPackExpansion2 =
5666 if (PackSize1 != PackSize2 && IsPackExpansion1 != IsPackExpansion2) {
5667 if (PackSize1 > PackSize2 && IsPackExpansion1)
5669 if (PackSize1 < PackSize2 && IsPackExpansion2)
5691 if (TPL1->
size() != TPL2->
size() || NumParams1 != NumParams2)
5707 for (
unsigned i = 0; i < NumParams1; ++i)
5723 bool AtLeastAsConstrained1, AtLeastAsConstrained2;
5728 if (AtLeastAsConstrained1 == AtLeastAsConstrained2)
5730 return AtLeastAsConstrained1 ? FT1 : FT2;
5738 bool Complain,
QualType TargetType) {
5739 if (SpecBegin == SpecEnd) {
5747 if (SpecBegin + 1 == SpecEnd)
5754 = cast<FunctionDecl>(*Best)->getPrimaryTemplate();
5755 assert(BestTemplate &&
"Not a function template specialization?");
5758 = cast<FunctionDecl>(*I)->getPrimaryTemplate();
5759 assert(Challenger &&
"Not a function template specialization?");
5764 BestTemplate = Challenger;
5770 bool Ambiguous =
false;
5773 = cast<FunctionDecl>(*I)->getPrimaryTemplate();
5795 const auto *FD = cast<FunctionDecl>(*I);
5797 FD->getPrimaryTemplate()->getTemplateParameters(),
5798 *FD->getTemplateSpecializationArgs());
5799 if (!TargetType.
isNull())
5801 Diag((*I)->getLocation(), PD);
5811 "not for function templates");
5813 isa<CXXConversionDecl>(FD1));
5815 isa<CXXConversionDecl>(FD2));
5828 bool AtLeastAsConstrained1, AtLeastAsConstrained2;
5833 if (AtLeastAsConstrained1 == AtLeastAsConstrained2)
5835 return AtLeastAsConstrained1 ? FD1 : FD2;
5845template<
typename TemplateLikeDecl>
5847 TemplateLikeDecl *P2,
5876 Deduced.resize(P2->getTemplateParameters()->size());
5878 S, P2->getTemplateParameters(), T2, T1, Info, Deduced,
TDF_None,
5889 const auto *TST1 = cast<TemplateSpecializationType>(T1);
5890 bool AtLeastAsSpecialized;
5892 AtLeastAsSpecialized =
5893 FinishTemplateArgumentDeduction(
5894 S, P2, true, TST1->template_arguments(),
5895 Deduced, Info) == TemplateDeductionResult::Success;
5897 return AtLeastAsSpecialized;
5904 template <
typename T1,
typename T2,
5905 std::enable_if_t<std::is_same_v<T1, T2>,
bool> =
true>
5906 T2 *operator()(T1 *, T2 *P2) {
5909 template <
typename T1,
typename T2,
5910 std::enable_if_t<!std::is_same_v<T1, T2>,
bool> =
true>
5911 T1 *operator()(T1 *, T2 *) {
5917struct TemplateArgumentListAreEqual {
5919 TemplateArgumentListAreEqual(
ASTContext &Ctx) : Ctx(Ctx) {}
5921 template <
typename T1,
typename T2,
5922 std::enable_if_t<std::is_same_v<T1, T2>,
bool> =
true>
5923 bool operator()(T1 *PS1, T2 *PS2) {
5925 Args2 = PS2->getTemplateArgs().asArray();
5927 for (
unsigned I = 0,
E = Args1.size(); I <
E; ++I) {
5931 llvm::FoldingSetNodeID IDA, IDB;
5932 Args1[I].Profile(IDA, Ctx);
5933 Args2[I].Profile(IDB, Ctx);
5940 template <
typename T1,
typename T2,
5941 std::enable_if_t<!std::is_same_v<T1, T2>,
bool> =
true>
5942 bool operator()(T1 *Spec, T2 *Primary) {
5944 Args2 = Primary->getInjectedTemplateArgs();
5946 for (
unsigned I = 0,
E = Args1.size(); I <
E; ++I) {
5950 llvm::FoldingSetNodeID IDA, IDB;
5951 Args1[I].Profile(IDA, Ctx);
5985template <
typename TemplateLikeDecl,
typename PrimaryDel>
5986static TemplateLikeDecl *
5989 constexpr bool IsMoreSpecialThanPrimaryCheck =
5990 !std::is_same_v<TemplateLikeDecl, PrimaryDel>;
5993 if (IsMoreSpecialThanPrimaryCheck && !Better1)
5997 if (IsMoreSpecialThanPrimaryCheck && !Better2)
6003 if (Better1 != Better2)
6004 return Better1 ? P1 : GetP2()(P1, P2);
6006 if (!Better1 && !Better2)
6011 auto *TST1 = cast<TemplateSpecializationType>(T1);
6012 auto *TST2 = cast<TemplateSpecializationType>(T2);
6015 assert(TST1->template_arguments().size() ==
6016 TST2->template_arguments().size());
6021 bool IsPackExpansion1 =
6023 bool IsPackExpansion2 =
6025 if (PackSize1 != PackSize2 && IsPackExpansion1 != IsPackExpansion2) {
6026 if (PackSize1 > PackSize2 && IsPackExpansion1)
6027 return GetP2()(P1, P2);
6028 if (PackSize1 < PackSize2 && IsPackExpansion2)
6057 if (!TemplateArgumentListAreEqual(S.
getASTContext())(P1, P2))
6061 P1->getAssociatedConstraints(AC1);
6062 P2->getAssociatedConstraints(AC2);
6063 bool AtLeastAsConstrained1, AtLeastAsConstrained2;
6065 (IsMoreSpecialThanPrimaryCheck && !AtLeastAsConstrained1))
6069 if (AtLeastAsConstrained1 == AtLeastAsConstrained2)
6071 return AtLeastAsConstrained1 ? P1 : GetP2()(P1, P2);
6106 "the partial specializations being compared should specialize"
6107 " the same template.");
6167 for (
unsigned I = 0, N =
P->size(); I != N; ++I) {
6176 Arg,
QualType(),
P->getParam(I)->getLocation()));
6195 Deduced.resize(A->
size());
6210 IsDeduced ? PackFold::ArgumentToParameter
6211 : PackFold::ParameterToArgument) !=
6221 bool AtLeastAsSpecialized;
6223 AtLeastAsSpecialized =
6224 ::FinishTemplateArgumentDeduction(
6225 *this, AArg, true, PArgs, Deduced, Info) ==
6226 TemplateDeductionResult::Success;
6228 return AtLeastAsSpecialized;
6232struct MarkUsedTemplateParameterVisitor :
6234 llvm::SmallBitVector &
Used;
6237 MarkUsedTemplateParameterVisitor(llvm::SmallBitVector &
Used,
6242 if (
T->getDepth() == Depth)
6243 Used[
T->getIndex()] =
true;
6248 if (
auto *TTP = llvm::dyn_cast_or_null<TemplateTemplateParmDecl>(
6250 if (TTP->getDepth() == Depth)
6251 Used[TTP->getIndex()] =
true;
6258 if (
auto *NTTP = dyn_cast<NonTypeTemplateParmDecl>(
E->getDecl()))
6259 if (NTTP->getDepth() == Depth)
6260 Used[NTTP->getIndex()] =
true;
6273 llvm::SmallBitVector &
Used) {
6275 MarkUsedTemplateParameterVisitor(
Used, Depth)
6276 .TraverseStmt(
const_cast<Expr *
>(
E));
6282 E = Expansion->getPattern();
6304 llvm::SmallBitVector &
Used) {
6311 OnlyDeduced, Depth,
Used);
6321 llvm::SmallBitVector &
Used) {
6322 if (
TemplateDecl *Template = Name.getAsTemplateDecl()) {
6324 = dyn_cast<TemplateTemplateParmDecl>(Template)) {
6325 if (TTP->getDepth() == Depth)
6326 Used[TTP->getIndex()] =
true;
6345 llvm::SmallBitVector &
Used) {
6363 case Type::BlockPointer:
6371 case Type::LValueReference:
6372 case Type::RValueReference:
6380 case Type::MemberPointer: {
6385 OnlyDeduced, Depth,
Used);
6389 case Type::DependentSizedArray:
6391 cast<DependentSizedArrayType>(
T)->getSizeExpr(),
6392 OnlyDeduced, Depth,
Used);
6396 case Type::ConstantArray:
6397 case Type::IncompleteArray:
6398 case Type::ArrayParameter:
6400 cast<ArrayType>(
T)->getElementType(),
6401 OnlyDeduced, Depth,
Used);
6404 case Type::ExtVector:
6406 cast<VectorType>(
T)->getElementType(),
6407 OnlyDeduced, Depth,
Used);
6410 case Type::DependentVector: {
6411 const auto *VecType = cast<DependentVectorType>(
T);
6418 case Type::DependentSizedExtVector: {
6420 = cast<DependentSizedExtVectorType>(
T);
6428 case Type::DependentAddressSpace: {
6430 cast<DependentAddressSpaceType>(
T);
6432 OnlyDeduced, Depth,
Used);
6435 OnlyDeduced, Depth,
Used);
6439 case Type::ConstantMatrix: {
6446 case Type::DependentSizedMatrix: {
6457 case Type::FunctionProto: {
6461 for (
unsigned I = 0, N = Proto->
getNumParams(); I != N; ++I) {
6466 if (!OnlyDeduced || I + 1 == N ||
6484 case Type::TemplateTypeParm: {
6491 case Type::SubstTemplateTypeParmPack: {
6493 = cast<SubstTemplateTypeParmPackType>(
T);
6497 OnlyDeduced, Depth,
Used);
6501 case Type::InjectedClassName:
6502 T = cast<InjectedClassNameType>(
T)->getInjectedSpecializationType();
6505 case Type::TemplateSpecialization: {
6507 = cast<TemplateSpecializationType>(
T);
6527 cast<ComplexType>(
T)->getElementType(),
6528 OnlyDeduced, Depth,
Used);
6534 cast<AtomicType>(
T)->getValueType(),
6535 OnlyDeduced, Depth,
Used);
6538 case Type::DependentName:
6541 cast<DependentNameType>(
T)->getQualifier(),
6542 OnlyDeduced, Depth,
Used);
6545 case Type::DependentTemplateSpecialization: {
6559 = cast<DependentTemplateSpecializationType>(
T);
6562 OnlyDeduced, Depth,
Used);
6572 OnlyDeduced, Depth,
Used);
6575 case Type::TypeOfExpr:
6578 cast<TypeOfExprType>(
T)->getUnderlyingExpr(),
6579 OnlyDeduced, Depth,
Used);
6582 case Type::Decltype:
6585 cast<DecltypeType>(
T)->getUnderlyingExpr(),
6586 OnlyDeduced, Depth,
Used);
6589 case Type::PackIndexing:
6592 OnlyDeduced, Depth,
Used);
6594 OnlyDeduced, Depth,
Used);
6598 case Type::UnaryTransform:
6602 OnlyDeduced, Depth,
Used);
6605 case Type::PackExpansion:
6607 cast<PackExpansionType>(
T)->getPattern(),
6608 OnlyDeduced, Depth,
Used);
6612 case Type::DeducedTemplateSpecialization:
6614 cast<DeducedType>(
T)->getDeducedType(),
6615 OnlyDeduced, Depth,
Used);
6617 case Type::DependentBitInt:
6619 cast<DependentBitIntType>(
T)->getNumBitsExpr(),
6620 OnlyDeduced, Depth,
Used);
6625 case Type::VariableArray:
6626 case Type::FunctionNoProto:
6629 case Type::ObjCInterface:
6630 case Type::ObjCObject:
6631 case Type::ObjCObjectPointer:
6632 case Type::UnresolvedUsing:
6635#define TYPE(Class, Base)
6636#define ABSTRACT_TYPE(Class, Base)
6637#define DEPENDENT_TYPE(Class, Base)
6638#define NON_CANONICAL_TYPE(Class, Base) case Type::Class:
6639#include "clang/AST/TypeNodes.inc"
6651 llvm::SmallBitVector &
Used) {
6669 OnlyDeduced, Depth,
Used);
6687 llvm::SmallBitVector &
Used) {
6693 bool OnlyDeduced,
unsigned Depth,
6694 llvm::SmallBitVector &
Used) {
6703 for (
unsigned I = 0, N = TemplateArgs.
size(); I != N; ++I)
6710 llvm::SmallBitVector &Deduced) {
6714 Deduced.resize(TemplateParams->
size());
6717 for (
unsigned I = 0, N =
Function->getNumParams(); I != N; ++I)
6719 true, TemplateParams->
getDepth(), Deduced);
6730 llvm::SmallBitVector Deduced(TemplateParams->
size());
6734 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 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 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)
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 TemplateDeductionResult DeduceTemplateArguments(Sema &S, TemplateParameterList *TemplateParams, ArrayRef< TemplateArgument > Ps, ArrayRef< TemplateArgument > As, TemplateDeductionInfo &Info, SmallVectorImpl< DeducedTemplateArgument > &Deduced, bool NumberOfArgumentsMustMatch, PackFold PackFold=PackFold::ParameterToArgument)
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 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 const TemplateSpecializationType * getLastTemplateSpecType(QualType QT)
Deduce the template arguments by comparing the template parameter type (which is a template-id) with ...
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 NamedDecl * getTemplateParameterWithDefault(Sema &S, NamedDecl *A, TemplateArgument Default)
Create a shallow copy of a given template parameter declaration, with empty source locations and usin...
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.
static QualType getPointeeType(const MemRegion *R)
Defines the clang::TypeLoc interface and its subclasses.
Allows QualTypes to be sorted and hence used in maps and sets.
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.
TemplateName getQualifiedTemplateName(NestedNameSpecifier *NNS, bool TemplateKeyword, TemplateName Template) const
Retrieve the template name that represents a qualified template name such as std::vector.
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 getFunctionTypeWithExceptionSpec(QualType Orig, const FunctionProtoType::ExceptionSpecInfo &ESI) const
Get a function type and produce the equivalent function type with the specified exception specificati...
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.
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.
QualType getUnqualifiedArrayType(QualType T, Qualifiers &Quals) const
Return this type as a completely-unqualified array type, capturing the qualifiers in Quals.
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.
TemplateDecl * getDescribedTemplate() const
If this is a declaration that describes some template, this method returns that template declaration.
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.
Represents a type that was referred to using an elaborated type keyword, e.g., struct S,...
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.
Classification Classify(ASTContext &Ctx) const
Classify - Classify this expression according to the C++11 expression taxonomy.
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
bool isFunctionTemplateSpecialization() const
Determine whether this function is a function template specialization.
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
void getAssociatedConstraints(SmallVectorImpl< const Expr * > &AC) const
Get the associated-constraints of this function declaration.
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
static ImplicitConceptSpecializationDecl * Create(const ASTContext &C, DeclContext *DC, SourceLocation SL, ArrayRef< TemplateArgument > ConvertedArgs)
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.
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...
static NonTypeTemplateParmDecl * Create(const ASTContext &C, DeclContext *DC, SourceLocation StartLoc, SourceLocation IdLoc, unsigned D, unsigned P, const IdentifierInfo *Id, QualType T, bool ParameterPack, TypeSourceInfo *TInfo)
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 as written in source code.
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...
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.
TemplateArgumentLoc getTrivialTemplateArgumentLoc(const TemplateArgument &Arg, QualType NTTPType, SourceLocation Loc, NamedDecl *TemplateParam=nullptr)
Allocate a TemplateArgumentLoc where all locations have been initialized to the given location.
TemplateDeductionResult DeduceTemplateArgumentsFromType(TemplateDecl *TD, QualType FromType, sema::TemplateDeductionInfo &Info)
Deduce the template arguments of the given template from FromType.
QualType ReplaceAutoType(QualType TypeWithAuto, QualType Replacement)
Completely replace the auto in TypeWithAuto by Replacement.
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 * getMoreConstrainedFunction(FunctionDecl *FD1, FunctionDecl *FD2)
Returns the more constrained function according to the rules of partial ordering by constraints (C++ ...
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...
ExpressionEvaluationContextRecord & parentEvaluationContext()
@ 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)
bool isTemplateTemplateParameterAtLeastAsSpecializedAs(TemplateParameterList *PParam, TemplateDecl *AArg, SourceLocation Loc, bool IsDeduced)
@ 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
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...
bool CheckTemplateArgumentList(TemplateDecl *Template, SourceLocation TemplateLoc, TemplateArgumentListInfo &TemplateArgs, bool PartialTemplateArgs, SmallVectorImpl< TemplateArgument > &SugaredConverted, SmallVectorImpl< TemplateArgument > &CanonicalConverted, bool UpdateArgsWithConversions=true, bool *ConstraintsNotSatisfied=nullptr, bool PartialOrderingTTP=false)
Check that the given template arguments can be provided to the given template, converting the argumen...
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.
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...
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.
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, bool ForDefaultArgumentSubstitution=false)
Retrieve the template argument list(s) that should be used to instantiate the definition of the given...
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.
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.
void DiagnoseAutoDeductionFailure(const VarDecl *VDecl, const Expr *Init)
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.
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.
ExprResult BuildExpressionFromDeclTemplateArgument(const TemplateArgument &Arg, QualType ParamType, SourceLocation Loc, NamedDecl *TemplateParam=nullptr)
Given a non-type template argument that refers to a declaration and the type of its corresponding non...
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"...
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.
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.
Expr * getRequiresClause()
The constraint-expression of the associated requires-clause.
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.
static TemplateTemplateParmDecl * Create(const ASTContext &C, DeclContext *DC, SourceLocation L, unsigned D, unsigned P, bool ParameterPack, IdentifierInfo *Id, bool Typename, TemplateParameterList *Params)
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.
CXXRecordDecl * getAsCXXRecordDecl() const
Retrieves the CXXRecordDecl that this type refers to, either because the type is a RecordType or beca...
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...
@ 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.
bool declaresSameEntity(const Decl *D1, const Decl *D2)
Determine whether two declarations declare the same entity.
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
@ EST_None
no exception specification
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.