46#include "llvm/ADT/APInt.h"
47#include "llvm/ADT/APSInt.h"
48#include "llvm/ADT/ArrayRef.h"
49#include "llvm/ADT/DenseMap.h"
50#include "llvm/ADT/FoldingSet.h"
51#include "llvm/ADT/SmallBitVector.h"
52#include "llvm/ADT/SmallPtrSet.h"
53#include "llvm/ADT/SmallVector.h"
54#include "llvm/Support/Casting.h"
55#include "llvm/Support/Compiler.h"
56#include "llvm/Support/ErrorHandling.h"
57#include "llvm/Support/SaveAndRestore.h"
115using namespace clang;
127 bool *HasDeducedAnyParam);
143 bool OnlyDeduced,
unsigned Depth,
144 llvm::SmallBitVector &
Used);
147 bool OnlyDeduced,
unsigned Level,
148 llvm::SmallBitVector &Deduced);
154 if (
const auto *IC = dyn_cast<ImplicitCastExpr>(E))
155 E = IC->getSubExpr();
156 else if (
const auto *CE = dyn_cast<ConstantExpr>(E))
157 E = CE->getSubExpr();
158 else if (
const auto *Subst = dyn_cast<SubstNonTypeTemplateParmExpr>(E))
159 E = Subst->getReplacement();
160 else if (
const auto *CCE = dyn_cast<CXXConstructExpr>(E)) {
162 if (CCE->getParenOrBraceRange().isValid())
165 assert(CCE->getNumArgs() >= 1 &&
"implicit construct expr should have 1 arg");
186 if (
const auto *NTTP = dyn_cast<NonTypeTemplateParmDecl>(Template))
187 return NTTP->getType();
194 if (
const auto *NTTP = dyn_cast<NonTypeTemplateParmDecl>(Template))
195 return NTTP->getDepth();
200 if (
const auto *NTTP = dyn_cast<NonTypeTemplateParmDecl>(Template))
201 return NTTP->getIndex();
214 if (
const auto *NTTP = dyn_cast<NonTypeTemplateParmDecl>(Template))
220 if (
const auto *NTTP = dyn_cast<NonTypeTemplateParmDecl>(Template))
221 return NTTP->isExpandedParameterPack();
226 if (
const auto *NTTP = dyn_cast<NonTypeTemplateParmDecl>(Template))
227 return NTTP->getLocation();
231 operator bool()
const {
return Template; }
245 if (
const auto *DRE = dyn_cast<DeclRefExpr>(E))
246 if (
const auto *NTTP = dyn_cast<NonTypeTemplateParmDecl>(DRE->getDecl()))
247 if (NTTP->getDepth() == Depth)
250 if (
const auto *ULE = dyn_cast<UnresolvedLookupExpr>(E);
251 ULE && (ULE->isConceptReference() || ULE->isVarDeclReference())) {
252 if (
auto *TTP = ULE->getTemplateTemplateDecl()) {
254 if (TTP->getDepth() == Depth)
270 X = NX->getUnderlyingDecl();
271 if (
NamedDecl *NY = dyn_cast<NamedDecl>(Y))
272 Y = NY->getUnderlyingDecl();
285 bool AggregateCandidateDeduction =
false) {
298 QualType XType =
X.getNonTypeTemplateArgumentType();
301 if (YType.
isNull() || !Context.hasSameType(XType, YType))
306 switch (
X.getKind()) {
308 llvm_unreachable(
"Non-deduced template arguments handled above");
315 X.wasDeducedFromArrayBound() ||
321 return X.wasDeducedFromArrayBound() ? Y :
X;
335 return X.wasDeducedFromArrayBound() ? Y :
X;
344 X.structurallyEquals(Y)))
352 Context.hasSameTemplateName(
X.getAsTemplate(), Y.
getAsTemplate()))
360 Context.hasSameTemplateName(
X.getAsTemplateOrTemplatePattern(),
372 llvm::FoldingSetNodeID ID1, ID2;
373 X.getAsExpr()->Profile(ID1, Context,
true);
376 return X.wasDeducedFromArrayBound() ? Y :
X;
383 assert(!
X.wasDeducedFromArrayBound());
396 X.getParamTypeForDecl());
433 (!AggregateCandidateDeduction &&
X.pack_size() != Y.
pack_size()))
445 if (Merged.isNull() && !(XA->isNull() && YA->isNull()))
447 NewPack.push_back(Merged);
450 NewPack.push_back(*XA);
460 llvm_unreachable(
"Invalid TemplateArgument Kind!");
473 bool *HasDeducedAnyParam) {
475 "deducing non-type template argument with wrong depth");
479 if (Result.isNull()) {
499 if (
auto *Expansion = dyn_cast<PackExpansionType>(ParamType))
500 ParamType = Expansion->getPattern();
514 S, TemplateParams, ParamType, ValueType, Info, Deduced,
528 bool *HasDeducedAnyParam) {
530 S, TemplateParams, NTTP,
532 DeducedFromArrayBound),
544 bool *HasDeducedAnyParam) {
566 bool *HasDeducedAnyParam) {
582 bool *HasDeducedAnyParam) {
594 bool *HasDeducedAnyParam) {
602 if (
auto *TempParam = dyn_cast<TemplateTemplateParmDecl>(ParamDecl)) {
609 unsigned StartPos = 0;
626 Arg, {StartPos, DefaultArguments.drop_front(StartPos)}))
630 S.
Context, Deduced[TempParam->getIndex()], NewDeduced);
631 if (Result.isNull()) {
632 Info.
Param = TempParam;
633 Info.
FirstArg = Deduced[TempParam->getIndex()];
638 Deduced[TempParam->getIndex()] = Result;
639 if (HasDeducedAnyParam)
640 *HasDeducedAnyParam =
true;
675 const TemplateSpecializationType *LastTST =
nullptr;
677 const TemplateSpecializationType *TST =
678 T->getAs<TemplateSpecializationType>();
681 if (!TST->isSugared())
684 T = TST->desugar().getTypePtr();
693 bool *HasDeducedAnyParam) {
698 TNP = TP->getTemplateName();
707 TP->castAsCanonical<TemplateSpecializationType>()->template_arguments();
709 const auto *TT = P->
castAs<InjectedClassNameType>();
710 TNP = TT->getTemplateName(S.
Context);
711 PResolved = TT->getTemplateArgs(S.
Context);
733 SA->getCanonicalTypeInternal()
734 ->castAs<TemplateSpecializationType>()
735 ->template_arguments();
749 S, TemplateParams, PResolved, AResolved, Info, Deduced,
757 const auto *TA = A->
getAs<TagType>();
763 TNA = TST->getTemplateName();
765 TNA = TA->getTemplateName(S.
Context);
784 S, TemplateParams, PResolved, AResolved, Info, Deduced,
790 assert(T->isCanonicalUnqualified());
792 switch (T->getTypeClass()) {
793 case Type::TypeOfExpr:
795 case Type::DependentName:
797 case Type::PackIndexing:
798 case Type::UnresolvedUsing:
799 case Type::TemplateTypeParm:
803 case Type::ConstantArray:
804 case Type::IncompleteArray:
805 case Type::VariableArray:
806 case Type::DependentSizedArray:
819 T->getCanonicalTypeInternal().getTypePtr());
857class PackDeductionScope {
865 bool DeducePackIfNotAlreadyDeduced =
false,
866 bool FinishingDeduction =
false)
867 : S(S), TemplateParams(TemplateParams), Deduced(Deduced), Info(Info),
868 DeducePackIfNotAlreadyDeduced(DeducePackIfNotAlreadyDeduced),
869 FinishingDeduction(FinishingDeduction) {
870 unsigned NumNamedPacks = addPacks(Pattern);
871 finishConstruction(NumNamedPacks);
875 PackDeductionScope(Sema &S, TemplateParameterList *TemplateParams,
876 SmallVectorImpl<DeducedTemplateArgument> &Deduced,
877 TemplateDeductionInfo &Info,
unsigned Index)
878 : S(S), TemplateParams(TemplateParams), Deduced(Deduced), Info(Info) {
880 finishConstruction(1);
884 void addPack(
unsigned Index) {
887 DeducedFromEarlierParameter = !Deduced[Index].isNull();
888 DeducedPack Pack(Index);
889 if (!FinishingDeduction) {
890 Pack.Saved = Deduced[Index];
891 Deduced[Index] = TemplateArgument();
897 if (UnsignedOrNone ExpandedPackExpansions =
899 FixedNumExpansions = ExpandedPackExpansions;
901 Packs.push_back(Pack);
904 unsigned addPacks(TemplateArgument Pattern) {
907 llvm::SmallBitVector SawIndices(TemplateParams->size());
908 llvm::SmallVector<TemplateArgument, 4> ExtraDeductions;
910 auto AddPack = [&](
unsigned Index) {
911 if (SawIndices[Index])
913 SawIndices[Index] =
true;
920 if (
auto *NTTP = dyn_cast<NonTypeTemplateParmDecl>(
921 TemplateParams->getParam(Index))) {
922 if (!NTTP->isExpandedParameterPack())
925 if (
auto *Expansion = dyn_cast<PackExpansionType>(
926 S.Context.getUnconstrainedType(NTTP->getType())))
927 ExtraDeductions.push_back(Expansion->getPattern());
933 auto Collect = [&](TemplateArgument Pattern) {
934 SmallVector<UnexpandedParameterPack, 2> Unexpanded;
935 S.collectUnexpandedParameterPacks(Pattern, Unexpanded);
936 for (
unsigned I = 0, N = Unexpanded.size(); I != N; ++I) {
937 unsigned Depth, Index;
939 std::tie(Depth, Index) = *DI;
943 if (Depth == Info.getDeducedDepth())
951 unsigned NumNamedPacks = Packs.size();
955 while (!ExtraDeductions.empty())
956 Collect(ExtraDeductions.pop_back_val());
958 return NumNamedPacks;
961 void finishConstruction(
unsigned NumNamedPacks) {
963 const TemplateArgument *PartialPackArgs =
nullptr;
964 unsigned NumPartialPackArgs = 0;
965 std::pair<unsigned, unsigned> PartialPackDepthIndex(-1u, -1u);
966 if (
auto *Scope = S.CurrentInstantiationScope)
967 if (
auto *Partial = Scope->getPartiallySubstitutedPack(
968 &PartialPackArgs, &NumPartialPackArgs))
974 bool IsExpanded =
true;
975 for (
unsigned I = 0; I != NumNamedPacks; ++I) {
976 if (Packs[I].Index >= Info.getNumExplicitArgs()) {
978 IsPartiallyExpanded =
false;
981 if (PartialPackDepthIndex ==
982 std::make_pair(Info.getDeducedDepth(), Packs[I].Index)) {
983 IsPartiallyExpanded =
true;
991 if (IsPartiallyExpanded)
992 PackElements += NumPartialPackArgs;
993 else if (IsExpanded && FixedNumExpansions)
994 PackElements += *FixedNumExpansions;
996 for (
auto &Pack : Packs) {
997 if (Info.PendingDeducedPacks.size() > Pack.Index)
998 Pack.Outer = Info.PendingDeducedPacks[Pack.Index];
1000 Info.PendingDeducedPacks.resize(Pack.Index + 1);
1001 Info.PendingDeducedPacks[Pack.Index] = &Pack;
1003 if (PartialPackDepthIndex ==
1004 std::make_pair(Info.getDeducedDepth(), Pack.Index)) {
1005 Pack.New.append(PartialPackArgs, PartialPackArgs + NumPartialPackArgs);
1011 ~PackDeductionScope() {
1012 for (
auto &Pack : Packs)
1013 Info.PendingDeducedPacks[Pack.Index] = Pack.Outer;
1017 UnsignedOrNone getSavedPackSizeIfAllEqual()
const {
1018 unsigned PackSize = Packs[0].Saved.pack_size();
1020 if (std::all_of(Packs.begin() + 1, Packs.end(), [&PackSize](
const auto &P) {
1021 return P.Saved.pack_size() == PackSize;
1024 return std::nullopt;
1029 bool isDeducedFromEarlierParameter()
const {
1030 return DeducedFromEarlierParameter;
1035 bool isPartiallyExpanded() {
return IsPartiallyExpanded; }
1040 bool hasFixedArity() {
return static_cast<bool>(FixedNumExpansions); }
1045 bool hasNextElement() {
1046 return !FixedNumExpansions || *FixedNumExpansions > PackElements;
1050 void nextPackElement() {
1054 if (!FinishingDeduction) {
1055 for (
auto &Pack : Packs) {
1056 DeducedTemplateArgument &DeducedArg = Deduced[Pack.Index];
1057 if (!Pack.New.empty() || !DeducedArg.
isNull()) {
1058 while (Pack.New.size() < PackElements)
1059 Pack.New.push_back(DeducedTemplateArgument());
1060 if (Pack.New.size() == PackElements)
1061 Pack.New.push_back(DeducedArg);
1063 Pack.New[PackElements] = DeducedArg;
1064 DeducedArg = Pack.New.size() > PackElements + 1
1065 ? Pack.New[PackElements + 1]
1066 : DeducedTemplateArgument();
1077 if (FinishingDeduction)
1078 return TemplateDeductionResult::Success;
1081 for (
auto &Pack : Packs) {
1083 if (!FinishingDeduction)
1084 Deduced[Pack.Index] = Pack.Saved;
1099 Pack.New.resize(PackElements);
1102 DeducedTemplateArgument NewPack;
1103 if (Pack.New.empty()) {
1107 TemplateArgument *ArgumentPack =
1108 new (S.Context) TemplateArgument[Pack.New.size()];
1109 std::copy(Pack.New.begin(), Pack.New.end(), ArgumentPack);
1110 NewPack = DeducedTemplateArgument(
1111 TemplateArgument(llvm::ArrayRef(ArgumentPack, Pack.New.size())),
1117 Pack.New[0].wasDeducedFromArrayBound());
1121 DeducedTemplateArgument *Loc;
1123 if (Pack.Outer->DeferredDeduction.isNull()) {
1126 Pack.Outer->DeferredDeduction = NewPack;
1129 Loc = &Pack.Outer->DeferredDeduction;
1131 Loc = &Deduced[Pack.Index];
1135 DeducedTemplateArgument OldPack = *Loc;
1137 S.Context, OldPack, NewPack, DeducePackIfNotAlreadyDeduced);
1139 Info.AggregateDeductionCandidateHasMismatchedArity =
1145 if (!
Result.isNull() && !Pack.DeferredDeduction.isNull()) {
1147 NewPack = Pack.DeferredDeduction;
1151 NamedDecl *Param = TemplateParams->getParam(Pack.Index);
1154 Info.FirstArg = OldPack;
1155 Info.SecondArg = NewPack;
1156 return TemplateDeductionResult::Inconsistent;
1162 if (*Expansions != PackElements) {
1165 return TemplateDeductionResult::IncompletePack;
1172 return TemplateDeductionResult::Success;
1177 TemplateParameterList *TemplateParams;
1178 SmallVectorImpl<DeducedTemplateArgument> &Deduced;
1179 TemplateDeductionInfo &Info;
1180 unsigned PackElements = 0;
1181 bool IsPartiallyExpanded =
false;
1182 bool DeducePackIfNotAlreadyDeduced =
false;
1183 bool DeducedFromEarlierParameter =
false;
1184 bool FinishingDeduction =
false;
1186 UnsignedOrNone FixedNumExpansions = std::nullopt;
1188 SmallVector<DeducedPack, 2> Packs;
1198 bool FinishingDeduction, T &&DeductFunc) {
1207 const PackExpansionType *Expansion
1208 = dyn_cast<PackExpansionType>(Params[
ParamIdx]);
1213 if (ArgIdx >= Args.size())
1225 DeductFunc(S, TemplateParams,
ParamIdx, ArgIdx,
1226 Params[
ParamIdx].getUnqualifiedType(),
1227 Args[ArgIdx].getUnqualifiedType(), Info, Deduced, POK);
1242 QualType Pattern = Expansion->getPattern();
1243 PackDeductionScope PackScope(S, TemplateParams, Deduced, Info, Pattern,
1245 FinishingDeduction);
1249 if (
ParamIdx + 1 == Params.size() || PackScope.hasFixedArity()) {
1250 for (; ArgIdx < Args.size() && PackScope.hasNextElement(); ++ArgIdx) {
1253 S, TemplateParams,
ParamIdx, ArgIdx,
1255 Info, Deduced, POK);
1258 PackScope.nextPackElement();
1279 if (NumExpansions && !PackScope.isPartiallyExpanded()) {
1280 for (
unsigned I = 0; I != *NumExpansions && ArgIdx < Args.size();
1282 PackScope.nextPackElement();
1288 if (
auto Result = PackScope.finish();
1304 if (ArgIdx < Args.size())
1347 llvm::SmallBitVector *HasDeducedParam) {
1348 return ::DeduceForEachType(
1349 S, TemplateParams, Params, Args, Info, Deduced, POK,
1355 bool HasDeducedAnyParamCopy =
false;
1357 S, TemplateParams, P, A, Info, Deduced, TDF, POK,
1358 false, &HasDeducedAnyParamCopy);
1359 if (HasDeducedAnyParam && HasDeducedAnyParamCopy)
1360 *HasDeducedAnyParam =
true;
1361 if (HasDeducedParam && HasDeducedAnyParamCopy)
1362 (*HasDeducedParam)[
ParamIdx] =
true;
1376 if (ParamQs == ArgQs)
1404 return Context.hasSameType(P, A);
1411 return Context.hasSameFunctionTypeIgnoringExceptionSpec(P, A);
1420 if (!Guide || !Guide->isImplicit())
1422 return Guide->getDeducedTemplate()->getTemplateParameters()->size();
1432 if (ParamRef->getPointeeType().getQualifiers())
1435 ParamRef->getPointeeType()->getAsCanonical<TemplateTypeParmType>();
1436 return TypeParm && TypeParm->getIndex() >= FirstInnerIndex;
1464 bool *HasDeducedAnyParam) {
1490 bool HasDeducedAnyParam;
1492 llvm::MapVector<const CXXRecordDecl *, MatchValue> Matches;
1494 auto AddBases = [&Visited, &ToVisit](
const CXXRecordDecl *RD) {
1497 assert(T->isRecordType() &&
"Base class that isn't a record?");
1498 if (Visited.insert(T->getAsCXXRecordDecl()).second)
1499 ToVisit.push_back(T);
1508 while (!ToVisit.empty()) {
1509 QualType NextT = ToVisit.pop_back_val();
1514 bool HasDeducedAnyParamCopy =
false;
1517 &HasDeducedAnyParamCopy);
1523 Matches.insert({RD, {DeducedCopy, HasDeducedAnyParamCopy}});
1534 if (Matches.size() > 1) {
1536 for (
const auto &
Match : Matches)
1537 AddBases(
Match.first);
1541 while (Matches.size() > 1 && !ToVisit.empty()) {
1542 const CXXRecordDecl *RD = ToVisit.pop_back_val()->getAsCXXRecordDecl();
1551 if (Matches.empty())
1553 if (Matches.size() > 1)
1556 std::swap(Matches.front().second.Deduced, Deduced);
1557 if (
bool HasDeducedAnyParamCopy = Matches.front().second.HasDeducedAnyParam;
1558 HasDeducedAnyParamCopy && HasDeducedAnyParam)
1559 *HasDeducedAnyParam = HasDeducedAnyParamCopy;
1600 bool *HasDeducedAnyParam) {
1604 if (
const auto *AExp = dyn_cast<PackExpansionType>(A))
1605 A = AExp->getPattern();
1700 if (
const auto *TTP = P->
getAsCanonical<TemplateTypeParmType>()) {
1706 unsigned Index = TTP->getIndex();
1733 "saw template type parameter with wrong depth");
1735 "Unresolved overloaded function");
1774 if (Result.isNull()) {
1778 case Decl::TemplateTypeParm:
1781 case Decl::NonTypeTemplateParm:
1784 case Decl::TemplateTemplateParm:
1788 llvm_unreachable(
"unexpected kind");
1795 Deduced[Index] = Result;
1796 if (HasDeducedAnyParam)
1797 *HasDeducedAnyParam =
true;
1809 if (P->
getAs<SubstTemplateTypeParmPackType>())
1855#define NON_CANONICAL_TYPE(Class, Base) \
1856 case Type::Class: llvm_unreachable("deducing non-canonical type: " #Class);
1857#define TYPE(Class, Base)
1858#include "clang/AST/TypeNodes.inc"
1860 case Type::TemplateTypeParm:
1861 case Type::SubstTemplateTypeParmPack:
1862 case Type::SubstBuiltinTemplatePack:
1863 llvm_unreachable(
"Type nodes handled above");
1875 case Type::VariableArray:
1877 case Type::FunctionNoProto:
1880 case Type::ObjCObject:
1881 case Type::ObjCInterface:
1882 case Type::ObjCObjectPointer:
1892 case Type::Complex: {
1897 S, TemplateParams, CP->getElementType(), CA->getElementType(), Info,
1899 false, HasDeducedAnyParam);
1903 case Type::Atomic: {
1908 S, TemplateParams, PA->getValueType(), AA->getValueType(), Info,
1910 false, HasDeducedAnyParam);
1914 case Type::Pointer: {
1925 PointeeType, Info, Deduced,
1928 false, HasDeducedAnyParam);
1932 case Type::LValueReference: {
1939 S, TemplateParams, RP->getPointeeType(), RA->getPointeeType(), Info,
1941 false, HasDeducedAnyParam);
1945 case Type::RValueReference: {
1952 S, TemplateParams, RP->getPointeeType(), RA->getPointeeType(), Info,
1954 false, HasDeducedAnyParam);
1958 case Type::IncompleteArray: {
1964 assert(IAP &&
"Template parameter not of incomplete array type");
1967 S, TemplateParams, IAP->getElementType(), IAA->getElementType(), Info,
1970 false, HasDeducedAnyParam);
1974 case Type::ConstantArray: {
1978 if (!CAA || CAA->getSize() != CAP->getSize())
1982 S, TemplateParams, CAP->getElementType(), CAA->getElementType(), Info,
1985 false, HasDeducedAnyParam);
1989 case Type::DependentSizedArray: {
1998 S, TemplateParams, DAP->getElementType(), AA->getElementType(),
2001 false, HasDeducedAnyParam);
2014 "saw non-type template parameter with wrong depth");
2015 if (
const auto *CAA = dyn_cast<ConstantArrayType>(AA)) {
2016 llvm::APSInt Size(CAA->getSize());
2020 Deduced, HasDeducedAnyParam);
2022 if (
const auto *DAA = dyn_cast<DependentSizedArrayType>(AA))
2023 if (DAA->getSizeExpr())
2025 S, TemplateParams, NTTP, DAA->getSizeExpr(), Info,
2035 case Type::FunctionProto: {
2041 if (FPP->getMethodQuals() != FPA->getMethodQuals() ||
2042 FPP->getRefQualifier() != FPA->getRefQualifier() ||
2043 FPP->isVariadic() != FPA->isVariadic())
2048 S, TemplateParams, FPP->getReturnType(), FPA->getReturnType(),
2050 false, HasDeducedAnyParam);
2056 S, TemplateParams, FPP->param_types(), FPA->param_types(), Info,
2069 Expr *NoexceptExpr = FPP->getNoexceptExpr();
2074 "saw non-type template parameter with wrong depth");
2077 switch (FPA->canThrow()) {
2091 if (
Expr *ArgNoexceptExpr = FPA->getNoexceptExpr())
2093 S, TemplateParams, NTTP, ArgNoexceptExpr, Info,
2107 case Type::InjectedClassName:
2116 case Type::TemplateSpecialization: {
2122 Deduced, HasDeducedAnyParam);
2129 Deduced, HasDeducedAnyParam);
2144 Deduced = DeducedOrig;
2149 Deduced, HasDeducedAnyParam);
2163 case Type::MemberPointer: {
2180 S, TemplateParams, PPT, APT, Info, Deduced, SubTDF,
2182 false, HasDeducedAnyParam);
2189 :
QualType(MPP->getQualifier().getAsType(), 0);
2190 assert(!TP.
isNull() &&
"member pointer with non-type class");
2195 :
QualType(MPA->getQualifier().getAsType(), 0)
2197 assert(!TA.
isNull() &&
"member pointer with non-type class");
2200 S, TemplateParams, TP, TA, Info, Deduced, SubTDF,
2202 false, HasDeducedAnyParam);
2210 case Type::BlockPointer: {
2216 S, TemplateParams, BPP->getPointeeType(), BPA->getPointeeType(), Info,
2218 false, HasDeducedAnyParam);
2224 case Type::ExtVector: {
2229 if (VP->getNumElements() != VA->getNumElements())
2231 ElementType = VA->getElementType();
2236 ElementType = VA->getElementType();
2242 S, TemplateParams, VP->getElementType(), ElementType, Info, Deduced,
2244 false, HasDeducedAnyParam);
2247 case Type::DependentVector: {
2253 S, TemplateParams, VP->getElementType(), VA->getElementType(),
2255 false, HasDeducedAnyParam);
2266 ArgSize = VA->getNumElements();
2273 HasDeducedAnyParam);
2279 S, TemplateParams, VP->getElementType(), VA->getElementType(),
2281 false, HasDeducedAnyParam);
2292 S, TemplateParams, NTTP, VA->getSizeExpr(), Info,
2302 case Type::DependentSizedExtVector: {
2308 S, TemplateParams, VP->getElementType(), VA->getElementType(),
2310 false, HasDeducedAnyParam);
2321 ArgSize = VA->getNumElements();
2326 S, TemplateParams, NTTP, ArgSize, S.
Context.
IntTy,
true, Info,
2333 S, TemplateParams, VP->getElementType(), VA->getElementType(),
2335 false, HasDeducedAnyParam);
2346 S, TemplateParams, NTTP, VA->getSizeExpr(), Info,
2357 case Type::ConstantMatrix: {
2364 if (MP->getNumRows() != MA->getNumRows() ||
2365 MP->getNumColumns() != MA->getNumColumns()) {
2370 S, TemplateParams, MP->getElementType(), MA->getElementType(), Info,
2372 false, HasDeducedAnyParam);
2375 case Type::DependentSizedMatrix: {
2385 false, HasDeducedAnyParam);
2390 auto DeduceMatrixArg =
2391 [&S, &Info, &Deduced, &TemplateParams, &HasDeducedAnyParam, POK](
2395 const auto *ACM = dyn_cast<ConstantMatrixType>(A);
2396 const auto *ADM = dyn_cast<DependentSizedMatrixType>(A);
2397 if (!ParamExpr->isValueDependent()) {
2398 std::optional<llvm::APSInt> ParamConst =
2399 ParamExpr->getIntegerConstantExpr(S.
Context);
2404 if ((ACM->*GetArgDimension)() == *ParamConst)
2409 Expr *ArgExpr = (ADM->*GetArgDimensionExpr)();
2410 if (std::optional<llvm::APSInt> ArgConst =
2412 if (*ArgConst == *ParamConst)
2423 llvm::APSInt ArgConst(
2425 ArgConst = (ACM->*GetArgDimension)();
2429 Deduced, HasDeducedAnyParam);
2433 S, TemplateParams, NTTP, (ADM->*GetArgDimensionExpr)(), Info,
2437 if (
auto Result = DeduceMatrixArg(MP->getRowExpr(), MA,
2443 return DeduceMatrixArg(MP->getColumnExpr(), MA,
2451 case Type::DependentAddressSpace: {
2457 S, TemplateParams, ASP->getPointeeType(), ASA->getPointeeType(),
2459 false, HasDeducedAnyParam);
2470 S, TemplateParams, NTTP, ASA->getAddrSpaceExpr(), Info,
2481 S, TemplateParams, ASP->getPointeeType(),
2484 false, HasDeducedAnyParam);
2495 S, TemplateParams, NTTP, ArgAddressSpace, S.
Context.
IntTy,
true,
2497 HasDeducedAnyParam);
2502 case Type::DependentBitInt: {
2506 if (IP->isUnsigned() != IA->isUnsigned())
2515 ArgSize = IA->getNumBits();
2518 S, TemplateParams, NTTP, ArgSize, S.
Context.
IntTy,
true, Info,
2523 if (IP->isUnsigned() != IA->isUnsigned())
2531 case Type::TypeOfExpr:
2533 case Type::DependentName:
2534 case Type::UnresolvedUsing:
2535 case Type::Decltype:
2536 case Type::UnaryTransform:
2537 case Type::DeducedTemplateSpecialization:
2538 case Type::PackExpansion:
2540 case Type::ArrayParameter:
2541 case Type::HLSLAttributedResource:
2542 case Type::HLSLInlineSpirv:
2543 case Type::OverflowBehavior:
2547 case Type::PackIndexing: {
2548 const PackIndexingType *PIT = P->
getAs<PackIndexingType>();
2549 if (PIT->hasSelectedType()) {
2551 S, TemplateParams, PIT->getSelectedType(), A, Info, Deduced, TDF,
2553 false, HasDeducedAnyParam);
2559 llvm_unreachable(
"Invalid Type Class!");
2567 bool *HasDeducedAnyParam) {
2576 llvm_unreachable(
"Null template argument in parameter list");
2584 false, HasDeducedAnyParam);
2596 HasDeducedAnyParam);
2602 llvm_unreachable(
"caller should handle pack expansions");
2657 HasDeducedAnyParam);
2662 Deduced, HasDeducedAnyParam);
2678 llvm_unreachable(
"Unknown template argument kind");
2683 llvm_unreachable(
"Argument packs should be expanded by the caller!");
2686 llvm_unreachable(
"Invalid TemplateArgument Kind!");
2699 if (ArgIdx == Args.size())
2706 assert(ArgIdx == Args.size() - 1 &&
"Pack not at the end of argument list?");
2709 return ArgIdx < Args.size();
2715 bool FoundPackExpansion =
false;
2716 for (
const auto &A : Args) {
2717 if (FoundPackExpansion)
2725 if (A.isPackExpansion())
2726 FoundPackExpansion =
true;
2756 for (
unsigned ArgIdx = 0,
ParamIdx = 0; ; ) {
2762 if (!Ps[
ParamIdx].isPackExpansion()) {
2767 return !FoldPackArgument && NumberOfArgumentsMustMatch
2771 if (As[ArgIdx].isPackExpansion()) {
2776 if (!FoldPackArgument)
2783 S, TemplateParams, Ps[
ParamIdx], Pattern, Info,
2791 if (Ps[
ParamIdx].isPackExpansion())
2797 S, TemplateParams, Ps[
ParamIdx], As[ArgIdx], Info,
2818 PackDeductionScope PackScope(S, TemplateParams, Deduced, Info, Pattern);
2824 PackScope.hasNextElement();
2826 if (!As[ArgIdx].isPackExpansion()) {
2827 if (!FoldPackParameter)
2829 if (FoldPackArgument)
2835 Deduced, HasDeducedAnyParam);
2839 PackScope.nextPackElement();
2844 return PackScope.finish();
2852 bool NumberOfArgumentsMustMatch) {
2853 return ::DeduceTemplateArguments(
2854 *
this, TemplateParams, Ps, As, Info, Deduced, NumberOfArgumentsMustMatch,
2865 llvm_unreachable(
"Can't get a NULL template argument here");
2914 llvm_unreachable(
"Invalid TemplateArgument Kind!");
2932 unsigned ArgumentPackIndex) {
2944 Template->getSourceRange().getEnd(), ArgumentPackIndex, CTAI,
2958 CanonicalPackedArgsBuilder;
2966 "deduced nested pack");
2972 S.
Diag(Param->getLocation(),
2973 diag::err_template_arg_deduced_incomplete_pack)
2977 if (ConvertArg(InnerArg, SugaredPackedArgsBuilder.size()))
2982 CanonicalPackedArgsBuilder.push_back(
2988 if (SugaredPackedArgsBuilder.empty()) {
2994 if (
auto *NTTP = dyn_cast<NonTypeTemplateParmDecl>(Param)) {
2999 S.
SubstType(NTTP->getType(), Args, NTTP->getLocation(),
3000 NTTP->getDeclName()).isNull())
3002 }
else if (
auto *TTP = dyn_cast<TemplateTemplateParmDecl>(Param)) {
3016 S.
Context, CanonicalPackedArgsBuilder));
3020 return ConvertArg(Arg, 0);
3032 unsigned NumAlreadyConverted,
bool *IsIncomplete) {
3033 for (
unsigned I = 0, N = TemplateParams->
size(); I != N; ++I) {
3040 if (Deduced[I].isNull() && Param->isTemplateParameterPack()) {
3042 PackDeductionScope(S, TemplateParams, Deduced, Info, I).finish();
3047 if (!Deduced[I].isNull()) {
3048 if (I < NumAlreadyConverted) {
3052 if (Param->isParameterPack() && CurrentInstantiationScope &&
3092 *IsIncomplete =
true;
3099 bool HasDefaultArg =
false;
3112 if (Rec->isLambda())
3113 if (
auto *Method = dyn_cast<CXXMethodDecl>(Rec->getDeclContext())) {
3115 ThisTypeQuals = Method->getMethodQualifiers();
3160 if (
auto *DC = dyn_cast<DeclContext>(D))
3183 bool DeducedArgsNeedReplacement =
false;
3184 if (
auto *TD = dyn_cast<ClassTemplatePartialSpecializationDecl>(
Template)) {
3185 TD->getAssociatedConstraints(AssociatedConstraints);
3186 DeducedArgsNeedReplacement = !TD->isClassScopeExplicitSpecialization();
3187 }
else if (
auto *TD =
3188 dyn_cast<VarTemplatePartialSpecializationDecl>(
Template)) {
3189 TD->getAssociatedConstraints(AssociatedConstraints);
3190 DeducedArgsNeedReplacement = !TD->isClassScopeExplicitSpecialization();
3193 AssociatedConstraints);
3196 std::optional<ArrayRef<TemplateArgument>> Innermost;
3199 if (!DeducedArgsNeedReplacement)
3200 Innermost = SugaredDeducedArgs;
3247 if (CopyDeducedArgs) {
3253 Info.
reset(SugaredDeducedArgumentList, CanonicalDeducedArgumentList);
3269 Info.
FirstArg = Ps[ArgIdx].getArgument();
3276 {},
false, InstCTAI,
3289 while (!Stack.empty()) {
3290 auto &Xs = Stack.back();
3295 auto &
X = Xs.front();
3297 Stack.emplace_back(
X.getPackAsArray());
3298 Xs = Xs.drop_front();
3301 assert(!
X.isNull());
3308 auto [Ps, P] = take(PsStack);
3309 auto [As, A] = take(AsStack);
3310 if (P.isNull() && A.isNull())
3313 PA = A.isPackExpansion() ? A.getPackExpansionPattern() : A;
3315 if (!P.isPackExpansion() && !A.isPackExpansion()) {
3317 (AsStack.empty() ? As.end() : AsStack.back().begin()) -
3323 if (P.isPackExpansion()) {
3324 Ps = Ps.drop_front();
3327 if (A.isPackExpansion()) {
3328 As = As.drop_front();
3332 Ps = Ps.drop_front(P.isPackExpansion() ? 0 : 1);
3333 As = As.drop_front(A.isPackExpansion() && !P.isPackExpansion() ? 0 : 1);
3335 assert(PsStack.empty());
3336 assert(AsStack.empty());
3355 for (
unsigned I = 0, N = Ps.size(); I != N; ++I)
3360 Info, CopyDeducedArgs);
3391template <
typename T>
3392static std::enable_if_t<IsPartialSpecialization<T>::value,
3397 if (Partial->isInvalidDecl())
3416 Deduced.resize(Partial->getTemplateParameters()->size());
3418 S, Partial->getTemplateParameters(),
3419 Partial->getTemplateArgs().asArray(), TemplateArgs, Info, Deduced,
3433 Result = ::FinishTemplateArgumentDeduction(
3434 S, Partial, Partial->getTemplateParameters(),
3435 Partial->getSpecializedTemplate(),
3437 Partial->getTemplateArgsAsWritten()->arguments(), TemplateArgs, Deduced,
3454 return ::DeduceTemplateArguments(*
this, Partial, TemplateArgs, Info);
3460 return ::DeduceTemplateArguments(*
this, Partial, TemplateArgs, Info);
3470 if (
const auto *CTD = dyn_cast<ClassTemplateDecl>(TD)) {
3472 PType =
Context.getCanonicalTagType(CTD->getTemplatedDecl());
3473 }
else if (
const auto *
AliasTemplate = dyn_cast<TypeAliasTemplateDecl>(TD)) {
3474 PType =
AliasTemplate->getTemplatedDecl()->getUnderlyingType();
3476 assert(
false &&
"Expected a class or alias template");
3495 return DeducedResult;
3505 Result = ::FinishTemplateArgumentDeduction(*this, TD, Deduced, Info);
3519 if (
const TemplateSpecializationType *Spec
3520 = T->getAs<TemplateSpecializationType>())
3521 return Spec->getTemplateName().getAsTemplateDecl() !=
nullptr;
3550 if (ExplicitTemplateArgs.
size() == 0) {
3553 for (
auto *P :
Function->parameters())
3554 ParamTypes.push_back(P->getType());
3579 ExplicitTemplateArgs, {},
3583 if (Index >= TemplateParams->
size())
3596 CanonicalExplicitArgumentList);
3608 unsigned PartiallySubstitutedPackIndex = -1u;
3616 if (!Expansions || Arg.
pack_size() < *Expansions) {
3626 assert(Proto &&
"Function template does not have a prototype?");
3634 SugaredExplicitArgumentList->
asArray(),
3644 nullptr, ExtParamInfos))
3660 ThisContext =
Method->getParent();
3661 ThisTypeQuals =
Method->getMethodQualifiers();
3675 Diag(
Function->getLocation(), diag::err_kern_type_not_void_return)
3686 nullptr, ExtParamInfos))
3710 Deduced.reserve(TemplateParams->
size());
3711 for (
unsigned I = 0, N = SugaredExplicitArgumentList->
size(); I != N; ++I) {
3713 if (I == PartiallySubstitutedPackIndex)
3716 Deduced.push_back(Arg);
3743 if (Context.hasSameUnqualifiedType(A, DeducedA))
3784 if (AQuals == DeducedAQuals) {
3802 bool ObjCLifetimeConversion =
false;
3805 ObjCLifetimeConversion) ||
3827 if (Context.hasSameUnqualifiedType(A, DeducedA))
3851 if (PD->isParameterPack()) {
3854 unsigned NumExpansions = NumArgs ? *NumArgs : 1;
3855 if (Idx + NumExpansions >
ParamIdx)
3857 Idx += NumExpansions;
3860 return std::nullopt;
3865 llvm_unreachable(
"parameter index would not be produced from template");
3920 bool ForOverloadSetAddressResolution,
3921 llvm::function_ref<
bool(
bool)> CheckNonDependent) {
3936 bool IsIncomplete =
false;
3941 NumExplicitlySpecified, PartialOverloading ? &IsIncomplete :
nullptr);
3950 Info.
reset(SugaredDeducedArgumentList, CanonicalDeducedArgumentList);
3959 if (CheckNonDependent(
true))
3971 if (!IsLambda && !IsIncomplete) {
3993 if (CheckNonDependent(
false))
4010 CanonicalDeducedArgumentList)
4021 if (IsLambda && !IsIncomplete) {
4046 if (OriginalCallArgs) {
4051 llvm::SmallDenseMap<std::pair<unsigned, QualType>,
QualType> DeducedATypes;
4052 for (
unsigned I = 0, N = OriginalCallArgs->size(); I != N; ++I) {
4056 unsigned ExplicitOffset =
4058 !ForOverloadSetAddressResolution)
4079 if (CacheEntry.
isNull()) {
4088 DeducedA = CacheEntry;
4103 auto [Pos, Inserted] =
4117 if (S.
getLangOpts().CPlusPlus14 && Fn->getReturnType()->isUndeducedType() &&
4122 if (Method->isImplicitObjectMemberFunction()) {
4125 if (!R.HasFormOfMemberPointer)
4129 Fn->getType(), std::nullopt, Method->getParent());
4132 if (!R.IsAddressOfOperand)
return Fn->getType();
4143 bool ParamWasReference,
4152 if (ParamWasReference)
4154 if (R.IsAddressOfOperand)
4211 if (ArgType.isNull())
continue;
4215 ArgType->isFunctionType())
4231 Deduced(TemplateParams->
size());
4234 S, TemplateParams, ParamType, ArgType, Info, Deduced, TDF,
4278 assert(Arg &&
"expected a non-null arg expression");
4280 ParamRefType !=
nullptr, FailedTSC);
4281 if (ArgType.isNull())
4287 if (ArgType->isIncompleteArrayType()) {
4288 assert(Arg &&
"expected a non-null arg expression");
4297 if (S.
getLangOpts().OpenCL && !ArgType.hasAddressSpace())
4311 if (ArgType->canDecayToPointerType())
4316 ArgType = ArgType.getUnqualifiedType();
4334 if (ArgType->isPointerType() || ArgType->isMemberPointerType() ||
4335 ArgType->isObjCObjectPointerType())
4362 bool DecomposedParam,
unsigned ArgIdx,
unsigned TDF,
4387 ElTy = ArrTy->getElementType();
4404 S, TemplateParams, 0, ElTy, E->getType(),
4406 OriginalCallArgs,
true, ArgIdx, TDF);
4414 if (
auto *DependentArrTy = dyn_cast_or_null<DependentSizedArrayType>(ArrTy)) {
4417 Info, DependentArrTy->getSizeExpr())) {
4426 S, TemplateParams, NTTP, llvm::APSInt(Size), T,
4427 true, Info,
false, Deduced,
4446 bool DecomposedParam,
unsigned ArgIdx,
unsigned TDF,
4449 QualType OrigParamType = ParamType;
4454 S, TemplateParams, FirstInnerIndex, ParamType, ArgType,
4455 ArgClassification, Arg, TDF, FailedTSC))
4459 if (
InitListExpr *ILE = dyn_cast_if_present<InitListExpr>(Arg))
4461 Deduced, OriginalCallArgs, ArgIdx, TDF);
4469 OriginalCallArgs.push_back(
4472 S, TemplateParams, ParamType, ArgType, Info, Deduced, TDF,
4481 bool PartialOverloading,
bool AggregateDeductionCandidate,
4484 bool ForOverloadSetAddressResolution,
4490 unsigned NumParams =
Function->getNumParams();
4491 bool HasExplicitObject =
false;
4492 int ExplicitObjectOffset = 0;
4500 if (!ForOverloadSetAddressResolution &&
4501 Function->hasCXXExplicitFunctionObjectParameter()) {
4502 HasExplicitObject =
true;
4503 ExplicitObjectOffset = 1;
4512 if (Args.size() <
Function->getMinRequiredExplicitArguments() &&
4513 !PartialOverloading)
4516 PartialOverloading)) {
4518 if (Proto->isTemplateVariadic())
4520 else if (!Proto->isVariadic())
4535 unsigned NumExplicitlySpecified = 0;
4536 if (ExplicitTemplateArgs) {
4539 Result = SubstituteExplicitTemplateArguments(
4540 FunctionTemplate, *ExplicitTemplateArgs, Deduced, ParamTypes, nullptr,
4548 NumExplicitlySpecified = Deduced.size();
4551 for (
unsigned I = 0; I != NumParams; ++I)
4552 ParamTypes.push_back(
Function->getParamDecl(I)->getType());
4558 auto DeduceCallArgument = [&](
QualType ParamType,
unsigned ArgIdx,
4559 bool ExplicitObjectArgument) {
4567 if (ExplicitObjectArgument) {
4570 *
this, TemplateParams, FirstInnerIndex, ParamType, ObjectType,
4571 ObjectClassification,
4572 nullptr, Info, Deduced, OriginalCallArgs,
4578 *
this, TemplateParams, FirstInnerIndex, ParamType,
4580 Args[ArgIdx], Info, Deduced, OriginalCallArgs,
false,
4585 Deduced.resize(TemplateParams->
size());
4587 for (
unsigned ParamIdx = 0, NumParamTypes = ParamTypes.size(), ArgIdx = 0;
4591 const PackExpansionType *ParamExpansion =
4592 dyn_cast<PackExpansionType>(ParamType);
4593 if (!ParamExpansion) {
4595 if (ArgIdx >= Args.size() && !(HasExplicitObject &&
ParamIdx == 0))
4598 ParamTypesForArgChecking.push_back(ParamType);
4600 if (
ParamIdx == 0 && HasExplicitObject) {
4604 if (
auto Result = DeduceCallArgument(ParamType, 0,
4611 if (
auto Result = DeduceCallArgument(ParamType, ArgIdx++,
4619 bool IsTrailingPack =
ParamIdx + 1 == NumParamTypes;
4621 QualType ParamPattern = ParamExpansion->getPattern();
4622 PackDeductionScope PackScope(*
this, TemplateParams, Deduced, Info,
4624 AggregateDeductionCandidate && IsTrailingPack);
4642 if (IsTrailingPack || PackScope.hasFixedArity()) {
4643 for (; ArgIdx < Args.size() && PackScope.hasNextElement();
4644 PackScope.nextPackElement(), ++ArgIdx) {
4645 ParamTypesForArgChecking.push_back(ParamPattern);
4646 if (
auto Result = DeduceCallArgument(ParamPattern, ArgIdx,
4655 UnsignedOrNone NumExpansions = ParamExpansion->getNumExpansions();
4656 if (NumExpansions && !PackScope.isPartiallyExpanded()) {
4657 for (
unsigned I = 0; I != *NumExpansions && ArgIdx < Args.size();
4659 ParamTypesForArgChecking.push_back(ParamPattern);
4662 PackScope.nextPackElement();
4664 }
else if (!IsTrailingPack && !PackScope.isPartiallyExpanded() &&
4665 PackScope.isDeducedFromEarlierParameter()) {
4679 PackScope.getSavedPackSizeIfAllEqual();
4680 if (!ArgPosAfterSubstitution)
4683 unsigned PackArgEnd = ArgIdx + *ArgPosAfterSubstitution;
4684 for (; ArgIdx < PackArgEnd && ArgIdx < Args.size(); ArgIdx++) {
4685 ParamTypesForArgChecking.push_back(ParamPattern);
4687 DeduceCallArgument(ParamPattern, ArgIdx,
4692 PackScope.nextPackElement();
4699 if (
auto Result = PackScope.finish();
4710 Result = FinishTemplateArgumentDeduction(
4711 FunctionTemplate, Deduced, NumExplicitlySpecified, Specialization, Info,
4712 &OriginalCallArgs, PartialOverloading, PartialOrdering,
4713 ForOverloadSetAddressResolution,
4714 [&, CallingCtx](bool OnlyInitializeNonUserDefinedConversions) {
4715 ContextRAII SavedContext(*this, CallingCtx);
4716 return CheckNonDependent(ParamTypesForArgChecking,
4717 OnlyInitializeNonUserDefinedConversions);
4720 if (Trap.hasErrorOccurred()) {
4730 bool AdjustExceptionSpec) {
4731 if (ArgFunctionType.
isNull())
4732 return ArgFunctionType;
4737 bool Rebuild =
false;
4740 if (EPI.ExtInfo.getCC() != CC) {
4741 EPI.ExtInfo = EPI.ExtInfo.withCallingConv(CC);
4745 bool NoReturn = FunctionTypeP->getNoReturnAttr();
4746 if (EPI.ExtInfo.getNoReturn() != NoReturn) {
4747 EPI.ExtInfo = EPI.ExtInfo.withNoReturn(NoReturn);
4751 if (AdjustExceptionSpec && (FunctionTypeP->hasExceptionSpec() ||
4753 EPI.ExceptionSpec = FunctionTypeP->getExtProtoInfo().ExceptionSpec;
4758 return ArgFunctionType;
4768 bool IsAddressOfFunction) {
4788 unsigned NumExplicitlySpecified = 0;
4790 if (ExplicitTemplateArgs) {
4793 Result = SubstituteExplicitTemplateArguments(
4794 FunctionTemplate, *ExplicitTemplateArgs, Deduced, ParamTypes,
4795 &FunctionType, Info);
4802 NumExplicitlySpecified = Deduced.size();
4808 if (!IsAddressOfFunction)
4812 Deduced.resize(TemplateParams->
size());
4816 bool HasDeducedReturnType =
false;
4818 Function->getReturnType()->getContainedAutoType()) {
4820 HasDeducedReturnType =
true;
4828 *
this, TemplateParams,
FunctionType, ArgFunctionType, Info, Deduced,
4837 Result = FinishTemplateArgumentDeduction(
4838 FunctionTemplate, Deduced, NumExplicitlySpecified, Specialization, Info,
4840 true, IsAddressOfFunction);
4847 if (HasDeducedReturnType && IsAddressOfFunction &&
4867 if (!IsAddressOfFunction) {
4873 if (HasDeducedReturnType) {
4882 if (!ArgFunctionType.
isNull()) {
4884 SpecializationType, ArgFunctionType)
4885 : !
Context.hasSameFunctionTypeIgnoringExceptionSpec(
4886 SpecializationType, ArgFunctionType)) {
4924 if (!IsReferenceP) {
4933 assert(!A->
isReferenceType() &&
"Reference types were handled above");
4939 P =
Context.getArrayDecayedType(P);
4944 P =
Context.getPointerType(P);
4970 Deduced.resize(TemplateParams->
size());
4999 ParamType, ObjectType, ObjectClassification,
5000 nullptr, Info, Deduced, OriginalCallArgs,
5007 *
this, TemplateParams, P, A, Info, Deduced, TDF,
5019 Result = FinishTemplateArgumentDeduction(
5020 ConversionTemplate, Deduced, 0, ConversionSpecialized, Info,
5021 &OriginalCallArgs, false,
5024 Specialization = cast_or_null<CXXConversionDecl>(ConversionSpecialized);
5033 bool IsAddressOfFunction) {
5036 IsAddressOfFunction);
5040 struct DependentAuto {
bool IsPack; };
5044 class SubstituteDeducedTypeTransform :
5047 bool ReplacementIsPack;
5052 SubstituteDeducedTypeTransform(
Sema &SemaRef, DependentAuto DA)
5054 ReplacementIsPack(DA.IsPack), UseTypeSugar(
true) {}
5056 SubstituteDeducedTypeTransform(Sema &SemaRef, QualType Replacement,
5057 bool UseTypeSugar =
true)
5058 : TreeTransform<SubstituteDeducedTypeTransform>(SemaRef),
5059 Replacement(Replacement), ReplacementIsPack(
false),
5060 UseTypeSugar(UseTypeSugar) {}
5062 QualType TransformDesugared(TypeLocBuilder &TLB, DeducedTypeLoc TL) {
5064 "unexpected unsugared replacement kind");
5065 QualType
Result = Replacement;
5066 TemplateTypeParmTypeLoc NewTL = TLB.
push<TemplateTypeParmTypeLoc>(
Result);
5071 QualType TransformAutoType(TypeLocBuilder &TLB, AutoTypeLoc TL) {
5082 return TransformDesugared(TLB, TL);
5084 QualType
Result = SemaRef.Context.getAutoType(
5085 Replacement, TL.
getTypePtr()->getKeyword(), Replacement.isNull(),
5086 ReplacementIsPack, TL.
getTypePtr()->getTypeConstraintConcept(),
5087 TL.
getTypePtr()->getTypeConstraintArguments());
5093 QualType TransformDeducedTemplateSpecializationType(
5094 TypeLocBuilder &TLB, DeducedTemplateSpecializationTypeLoc TL) {
5096 return TransformDesugared(TLB, TL);
5098 QualType
Result = SemaRef.Context.getDeducedTemplateSpecializationType(
5100 Replacement, Replacement.isNull());
5101 auto NewTL = TLB.
push<DeducedTemplateSpecializationTypeLoc>(
Result);
5112 bool TransformExceptionSpec(SourceLocation Loc,
5113 FunctionProtoType::ExceptionSpecInfo &ESI,
5114 SmallVectorImpl<QualType> &Exceptions,
5120 return inherited::TransformExceptionSpec(Loc, ESI, Exceptions, Changed);
5123 QualType Apply(TypeLoc TL) {
5128 return TransformType(TLB, TL);
5144 Deduced,
TypeLoc.getNameLoc())));
5145 for (
unsigned I = 0,
C =
TypeLoc.getNumArgs(); I !=
C; ++I)
5175 llvm::raw_string_ostream OS(Buf);
5176 OS <<
"'" <<
Concept->getName();
5177 if (
TypeLoc.hasExplicitTemplateArgs()) {
5178 printTemplateArgumentList(
5180 Type.getTypeConstraintConcept()->getTemplateParameters());
5184 diag::err_placeholder_constraints_not_satisfied)
5195 bool IgnoreConstraints,
5198 if (
Init->containsErrors())
5204 if (
Init->getType()->isNonOverloadPlaceholderType() || AT->isDecltypeAuto()) {
5211 DependentAuto DependentResult = {
5214 if (!DependentDeduction &&
5216 Init->containsUnexpandedParameterPack())) {
5217 Result = SubstituteDeducedTypeTransform(*
this, DependentResult).Apply(
Type);
5218 assert(!
Result.isNull() &&
"substituting DependentTy can't fail");
5223 auto *String = dyn_cast<StringLiteral>(
Init);
5225 Diag(
Type.getBeginLoc(), diag::ext_c23_auto_non_plain_identifier);
5227 Result = SubstituteDeducedTypeTransform(*
this, DependentResult).Apply(TL);
5228 assert(!
Result.isNull() &&
"substituting DependentTy can't fail");
5234 Diag(
Type.getBeginLoc(), diag::ext_c23_auto_non_plain_identifier);
5237 auto *InitList = dyn_cast<InitListExpr>(
Init);
5239 Diag(
Init->getBeginLoc(), diag::err_auto_init_list_from_c)
5252 if (AT->isDecltypeAuto()) {
5254 Diag(
Init->getBeginLoc(), diag::err_decltype_auto_initializer_list);
5259 assert(!DeducedType.
isNull());
5267 nullptr,
false,
false,
false);
5271 Context, Loc, Loc, TemplParamPtr, Loc,
nullptr);
5277 if (!
Type.getType().getNonReferenceType()->
getAs<AutoType>())
5281 for (
Expr *
Init : InitList->inits()) {
5287 *
this, TemplateParamsSt.get(), 0, TemplArg,
Init->getType(),
5296 <<
Init->getSourceRange();
5304 DeducedFromInitRange =
Init->getSourceRange();
5308 Diag(Loc, diag::err_auto_bitfield);
5312 SubstituteDeducedTypeTransform(*
this, TemplArg).Apply(
Type);
5313 assert(!FuncParam.
isNull() &&
5314 "substituting template parameter for 'auto' failed");
5316 *
this, TemplateParamsSt.get(), 0, FuncParam,
Init->getType(),
5319 false, 0, 0, FailedTSC);
5327 DeducedType = Deduced[0].getAsType();
5331 if (DeducedType.
isNull())
5342 DeducedType =
Context.getCommonSugaredType(
Result, DeducedType);
5345 if (AT->isConstrained() && !IgnoreConstraints &&
5347 *
this, *AT,
Type.getContainedAutoTypeLoc(), DeducedType))
5350 Result = SubstituteDeducedTypeTransform(*
this, DeducedType).Apply(
Type);
5358 assert((
bool)InitList == OriginalArg.DecomposedParam &&
5359 "decomposed non-init-list in auto deduction?");
5373 assert(TypeToReplaceAuto !=
Context.DependentTy);
5374 return SubstituteDeducedTypeTransform(*
this, TypeToReplaceAuto)
5375 .TransformType(TypeWithAuto);
5380 assert(TypeToReplaceAuto !=
Context.DependentTy);
5381 return SubstituteDeducedTypeTransform(*
this, TypeToReplaceAuto)
5382 .TransformType(TypeWithAuto);
5386 return SubstituteDeducedTypeTransform(
5389 .TransformType(TypeWithAuto);
5394 return SubstituteDeducedTypeTransform(
5397 .TransformType(TypeWithAuto);
5402 return SubstituteDeducedTypeTransform(*
this, TypeToReplaceAuto,
5404 .TransformType(TypeWithAuto);
5409 return SubstituteDeducedTypeTransform(*
this, TypeToReplaceAuto,
5411 .TransformType(TypeWithAuto);
5419 ? diag::err_init_capture_deduction_failure_from_init_list
5420 : diag::err_auto_var_deduction_failure_from_init_list)
5424 VDecl->
isInitCapture() ? diag::err_init_capture_deduction_failure
5425 : diag::err_auto_var_deduction_failure)
5427 <<
Init->getSourceRange();
5443 CallOp->getDescribedFunctionTemplate(), Args, Loc);
5444 if (!CallOp || CallOp->isInvalidDecl())
5449 if (CallOp->getReturnType()->isUndeducedType()) {
5456 if (CallOp->isInvalidDecl())
5458 assert(!CallOp->getReturnType()->isUndeducedType() &&
5459 "failed to deduce lambda return type");
5469 RetType =
Context.getPointerType(RetType);
5472 RetType =
Context.getBlockPointerType(RetType);
5474 Context.adjustDeducedFunctionResultType(FD, RetType);
5486 Diag(Loc, diag::err_auto_fn_used_before_defined) << FD;
5490 return StillUndeduced;
5504 CallOp->getDescribedFunctionTemplate(), Args, Loc);
5505 if (!CallOp || CallOp->isInvalidDecl())
5533 assert(Method && !Method->isExplicitObjectMemberFunction() &&
5534 "expected a member function with no explicit object parameter");
5536 RawType = Context.getQualifiedType(RawType, Method->getMethodQualifiers());
5537 if (Method->getRefQualifier() ==
RQ_RValue ||
5538 (IsOtherRvr && Method->getRefQualifier() ==
RQ_None))
5539 return Context.getRValueReferenceType(RawType);
5540 return Context.getLValueReferenceType(RawType);
5551 bool IsIncompleteSubstitution =
false;
5560 if (IsDeductionGuide) {
5562 P = Injected->getDecl()->getCanonicalTemplateSpecializationType(
5567 if (InstP.
isNull() && !IsIncompleteSubstitution)
5569 if (!CheckConsistency)
5571 if (IsIncompleteSubstitution)
5576 if (
auto *PA = dyn_cast<PackExpansionType>(A);
5578 A = PA->getPattern();
5581 if (IsDeductionGuide) {
5582 if (
auto *Injected = T1->getAsCanonical<InjectedClassNameType>())
5583 T1 = Injected->getDecl()->getCanonicalTemplateSpecializationType(
5585 if (
auto *Injected = T2->getAsCanonical<InjectedClassNameType>())
5586 T2 = Injected->getDecl()->getCanonicalTemplateSpecializationType(
5604 bool IsIncomplete =
false;
5620 Info.
reset(SugaredDeducedArgumentList, CanonicalDeducedArgumentList);
5639 assert(Proto1 && Proto2 &&
"Function templates must have prototypes");
5655 Proto1->
isVariadic() == Proto2->isVariadic() &&
5656 "shouldn't partial order functions with different qualifiers in a "
5657 "context where the function type is used");
5659 assert(Args1.empty() && Args2.empty() &&
5660 "Only call context should have arguments");
5662 Args2 = Proto2->getParamTypes();
5669 bool HasDeducedAnyParamFromReturnType =
false;
5672 S, TemplateParams, Proto2->getReturnType(), Proto1->
getReturnType(),
5675 &HasDeducedAnyParamFromReturnType) !=
5680 llvm::SmallBitVector HasDeducedParam;
5682 HasDeducedParam.resize(Args2.size());
5686 &HasDeducedParam) !=
5701 bool AtLeastAsSpecialized;
5703 AtLeastAsSpecialized =
5704 ::FinishTemplateArgumentDeduction(
5705 S, FT2, Deduced, Info,
5706 [&](Sema &S, FunctionTemplateDecl *FTD,
5707 ArrayRef<TemplateArgument> DeducedArgs) {
5712 if (TPOC != TPOC_Call) {
5713 if (auto TDR = ::CheckDeductionConsistency(
5714 S, FTD, std::nullopt,
5715 Proto2->getReturnType(), Proto1->getReturnType(),
5717 HasDeducedAnyParamFromReturnType);
5718 TDR != TemplateDeductionResult::Success)
5722 if (TPOC == TPOC_Conversion)
5723 return TemplateDeductionResult::Success;
5725 return ::DeduceForEachType(
5726 S, TemplateParams, Args2, Args1, Info, Deduced,
5727 PartialOrderingKind::Call, true,
5728 [&](Sema &S, TemplateParameterList *, int ParamIdx,
5729 UnsignedOrNone ArgIdx, QualType P, QualType A,
5730 TemplateDeductionInfo &Info,
5731 SmallVectorImpl<DeducedTemplateArgument> &Deduced,
5732 PartialOrderingKind) {
5733 if (ArgIdx && *ArgIdx >= static_cast<unsigned>(Args1Offset))
5734 ArgIdx = *ArgIdx - Args1Offset;
5736 ArgIdx = std::nullopt;
5737 return ::CheckDeductionConsistency(
5738 S, FTD, ArgIdx, P, A, DeducedArgs,
5739 HasDeducedParam[ParamIdx]);
5743 if (!AtLeastAsSpecialized || Trap.hasErrorOccurred())
5752 unsigned ArgIdx = 0, NumArgs = Deduced.size();
5753 for (; ArgIdx != NumArgs; ++ArgIdx)
5754 if (Deduced[ArgIdx].isNull())
5757 if (ArgIdx == NumArgs) {
5764 llvm::SmallBitVector UsedParameters(TemplateParams->size());
5767 for (
unsigned I = 0, N = Args2.size(); I != N; ++I)
5769 TemplateParams->getDepth(), UsedParameters);
5775 TemplateParams->getDepth(), UsedParameters);
5800 S.Context.getFunctionTypeWithExceptionSpec(FD2->getType(),
EST_None),
5801 false, TemplateParams->getDepth(), UsedParameters);
5805 for (; ArgIdx != NumArgs; ++ArgIdx)
5808 if (Deduced[ArgIdx].isNull() && UsedParameters[ArgIdx])
5820 const TemplateSpecializationType *TST1,
5821 const TemplateSpecializationType *TST2) {
5823 As2 = TST2->template_arguments();
5829 assert(As1.size() == As2.size());
5831 unsigned PackSize1 = TA1.
pack_size(), PackSize2 = TA2.pack_size();
5832 bool IsPackExpansion1 =
5834 bool IsPackExpansion2 =
5835 PackSize2 && TA2.pack_elements().back().isPackExpansion();
5836 if (PackSize1 == PackSize2 && IsPackExpansion1 == IsPackExpansion2)
5838 if (PackSize1 > PackSize2 && IsPackExpansion1)
5840 if (PackSize1 < PackSize2 && IsPackExpansion2)
5849 bool PartialOverloading) {
5854 bool ShouldConvert1 =
false;
5855 bool ShouldConvert2 =
false;
5856 bool Args1Offset =
false;
5857 bool Args2Offset =
false;
5868 const CXXMethodDecl *Method1 = dyn_cast<CXXMethodDecl>(FD1);
5869 const CXXMethodDecl *Method2 = dyn_cast<CXXMethodDecl>(FD2);
5880 bool NonStaticMethod1 = Method1 && !Method1->isStatic(),
5881 NonStaticMethod2 = Method2 && !Method2->
isStatic();
5884 Params2Begin = Proto2->param_type_begin();
5886 size_t NumComparedArguments = NumCallArguments1;
5889 (NonStaticMethod1 && NonStaticMethod2) ||
5890 (OO !=
OO_None && OO != OO_Call && OO != OO_Subscript)) {
5892 NonStaticMethod1 && !Method1->hasCXXExplicitFunctionObjectParameter();
5895 NumComparedArguments += 1;
5897 if (ShouldConvert1) {
5901 : Proto2->param_type_begin()[0]->isRValueReferenceType();
5904 RawObj1Ty, IsRValRef2);
5905 Args1.push_back(Obj1Ty);
5908 if (ShouldConvert2) {
5911 ? Method1->getRefQualifier() ==
RQ_RValue
5915 RawObj2Ty, IsRValRef1);
5916 Args2.push_back(Obj2Ty);
5920 if (NonStaticMethod1 && Method1->hasCXXExplicitFunctionObjectParameter())
5925 Args1.insert(Args1.end(), Params1Begin, Proto1->
param_type_end());
5926 Args2.insert(Args2.end(), Params2Begin, Proto2->param_type_end());
5931 Args1.resize(std::min(Args1.size(), NumComparedArguments));
5932 Args2.resize(std::min(Args2.size(), NumComparedArguments));
5935 std::reverse(Args2.begin(), Args2.end());
5937 assert(!
Reversed &&
"Only call context could have reversed arguments");
5940 Args2, Args2Offset);
5942 Args1, Args1Offset);
5946 if (Better1 != Better2)
5947 return Better1 ? FT1 : FT2;
5949 if (!Better1 && !Better2)
5958 Param1.reserve(FD1->
param_size() + ShouldConvert1);
5960 Param1.push_back(Obj1Ty);
5962 Param1.push_back(P->getType());
5965 Param2.reserve(FD2->
param_size() + ShouldConvert2);
5967 Param2.push_back(Obj2Ty);
5969 Param2.push_back(P->getType());
5971 unsigned NumParams1 = Param1.size();
5972 unsigned NumParams2 = Param2.size();
5978 if (Variadic1 != Variadic2) {
5979 if (Variadic1 && NumParams1 > NumParams2)
5981 if (Variadic2 && NumParams2 > NumParams1)
5988 for (
int i = 0, e = std::min(NumParams1, NumParams2);
5989 !PartialOverloading && i < e; ++i) {
5990 QualType T1 = Param1[i].getCanonicalType();
5991 QualType T2 = Param2[i].getCanonicalType();
5992 auto *TST1 = dyn_cast<TemplateSpecializationType>(T1);
5993 auto *TST2 = dyn_cast<TemplateSpecializationType>(T2);
6005 "unknown MoreSpecializedTrailingPackTieBreakerResult value");
6008 if (!
Context.getLangOpts().CPlusPlus20)
6024 if (TPL1->
size() != TPL2->
size() || NumParams1 != NumParams2)
6040 for (
unsigned i = 0; i < NumParams1; ++i)
6041 if (!
Context.hasSameUnqualifiedType(Param1[i], Param2[i]))
6056 bool AtLeastAsConstrained1, AtLeastAsConstrained2;
6061 if (AtLeastAsConstrained1 == AtLeastAsConstrained2)
6063 return AtLeastAsConstrained1 ? FT1 : FT2;
6071 bool Complain,
QualType TargetType) {
6072 if (SpecBegin == SpecEnd) {
6074 Diag(Loc, NoneDiag);
6080 if (SpecBegin + 1 == SpecEnd)
6088 assert(BestTemplate &&
"Not a function template specialization?");
6092 assert(Challenger &&
"Not a function template specialization?");
6097 BestTemplate = Challenger;
6123 Diag(Loc, AmbigDiag);
6130 FD->getPrimaryTemplate()->getTemplateParameters(),
6131 *FD->getTemplateSpecializationArgs());
6132 if (!TargetType.
isNull())
6134 Diag((*I)->getLocation(), PD);
6144 "not for function templates");
6161 bool AtLeastAsConstrained1, AtLeastAsConstrained2;
6166 if (AtLeastAsConstrained1 == AtLeastAsConstrained2)
6168 return AtLeastAsConstrained1 ? FD1 : FD2;
6180template <
typename TemplateLikeDecl>
6182 TemplateLikeDecl *P2,
6212 Deduced.resize(P2->getTemplateParameters()->size());
6214 S, P2->getTemplateParameters(), T2, T1, Info, Deduced,
TDF_None,
6233 Result = ::FinishTemplateArgumentDeduction(
6234 S, P2, P2->getTemplateParameters(), Template,
6235 true, Ps, As, Deduced, Info,
6245 template <
typename T1,
typename T2,
6246 std::enable_if_t<std::is_same_v<T1, T2>,
bool> =
true>
6247 T2 *operator()(T1 *, T2 *P2) {
6250 template <
typename T1,
typename T2,
6251 std::enable_if_t<!std::is_same_v<T1, T2>,
bool> =
true>
6252 T1 *operator()(T1 *, T2 *) {
6258struct TemplateArgumentListAreEqual {
6260 TemplateArgumentListAreEqual(ASTContext &Ctx) : Ctx(Ctx) {}
6262 template <
typename T1,
typename T2,
6263 std::enable_if_t<std::is_same_v<T1, T2>,
bool> =
true>
6264 bool operator()(T1 *PS1, T2 *PS2) {
6265 ArrayRef<TemplateArgument> Args1 = PS1->getTemplateArgs().asArray(),
6266 Args2 = PS2->getTemplateArgs().asArray();
6268 for (
unsigned I = 0, E = Args1.size(); I < E; ++I) {
6272 llvm::FoldingSetNodeID IDA, IDB;
6273 Args1[I].Profile(IDA, Ctx);
6274 Args2[I].Profile(IDB, Ctx);
6281 template <
typename T1,
typename T2,
6282 std::enable_if_t<!std::is_same_v<T1, T2>,
bool> =
true>
6283 bool operator()(T1 *Spec, T2 *Primary) {
6284 ArrayRef<TemplateArgument> Args1 = Spec->getTemplateArgs().asArray(),
6285 Args2 = Primary->getInjectedTemplateArgs(Ctx);
6287 for (
unsigned I = 0, E = Args1.size(); I < E; ++I) {
6291 llvm::FoldingSetNodeID IDA, IDB;
6292 Args1[I].Profile(IDA, Ctx);
6326template <
typename TemplateLikeDecl,
typename PrimaryDel>
6327static TemplateLikeDecl *
6330 constexpr bool IsMoreSpecialThanPrimaryCheck =
6331 !std::is_same_v<TemplateLikeDecl, PrimaryDel>;
6334 if constexpr (IsMoreSpecialThanPrimaryCheck)
6337 P2T = P2->getSpecializedTemplate();
6340 if (IsMoreSpecialThanPrimaryCheck && !Better1)
6344 P1->getSpecializedTemplate(), Info);
6345 if (IsMoreSpecialThanPrimaryCheck && !Better2)
6351 if (Better1 != Better2)
6352 return Better1 ? P1 : GetP2()(P1, P2);
6354 if (!Better1 && !Better2)
6363 return GetP2()(P1, P2);
6392 if (!TemplateArgumentListAreEqual(S.
getASTContext())(P1, P2))
6396 P1->getAssociatedConstraints(AC1);
6397 P2->getAssociatedConstraints(AC2);
6398 bool AtLeastAsConstrained1, AtLeastAsConstrained2;
6400 (IsMoreSpecialThanPrimaryCheck && !AtLeastAsConstrained1))
6404 if (AtLeastAsConstrained1 == AtLeastAsConstrained2)
6406 return AtLeastAsConstrained1 ? P1 : GetP2()(P1, P2);
6441 "the partial specializations being compared should specialize"
6442 " the same template.");
6460 Context.canonicalizeTemplateArguments(PrimaryCanonArgs);
6512 for (
unsigned I = 0, N = P->
size(); I != N; ++I) {
6537 if (StrictPackMatch)
6544 Deduced.resize(A->
size());
6558 *
this, A, AArgs, PArgs, Info, Deduced,
6564 *StrictPackMatch =
true;
6568 Diag(AArg->
getLocation(), diag::err_template_param_list_different_arity)
6578 diag::err_inconsistent_deduction)
6599 llvm_unreachable(
"Unexpected Result");
6604 TDK = ::FinishTemplateArgumentDeduction(
6605 *this, AArg, AArg->getTemplateParameters(), AArg, PartialOrdering,
6606 AArgs, PArgs, Deduced, Info, false);
6616 assert(PArg->
isInvalidDecl() &&
"Unexpected NonDeducedMismatch");
6640 llvm_unreachable(
"Unexpected Result");
6642 llvm_unreachable(
"Unexpected TDK");
6647 llvm::SmallBitVector &
Used;
6649 bool VisitDeclRefTypes =
true;
6651 MarkUsedTemplateParameterVisitor(llvm::SmallBitVector &
Used,
unsigned Depth,
6652 bool VisitDeclRefTypes =
true)
6653 :
Used(
Used), Depth(Depth), VisitDeclRefTypes(VisitDeclRefTypes) {}
6655 bool VisitTemplateTypeParmType(TemplateTypeParmType *T)
override {
6656 if (T->getDepth() == Depth)
6657 Used[T->getIndex()] =
true;
6662 if (
auto *TTP = llvm::dyn_cast_or_null<TemplateTemplateParmDecl>(
6664 if (TTP->getDepth() == Depth)
6665 Used[TTP->getIndex()] =
true;
6670 bool VisitDeclRefExpr(DeclRefExpr *E)
override {
6671 if (
auto *NTTP = dyn_cast<NonTypeTemplateParmDecl>(E->
getDecl()))
6672 if (NTTP->getDepth() == Depth)
6673 Used[NTTP->getIndex()] =
true;
6674 if (VisitDeclRefTypes)
6679 bool VisitUnresolvedLookupExpr(UnresolvedLookupExpr *ULE)
override {
6682 if (TTP->getDepth() == Depth)
6683 Used[TTP->getIndex()] =
true;
6691 bool TraverseSizeOfPackExpr(SizeOfPackExpr *SOPE)
override {
6692 return TraverseDecl(SOPE->
getPack());
6704 llvm::SmallBitVector &
Used) {
6706 MarkUsedTemplateParameterVisitor(
Used, Depth)
6707 .TraverseStmt(
const_cast<Expr *
>(E));
6713 E = Expansion->getPattern();
6716 if (
const auto *ULE = dyn_cast<UnresolvedLookupExpr>(E);
6719 Used[TTP->getIndex()] =
true;
6742 bool OnlyDeduced,
unsigned Depth,
6743 llvm::SmallBitVector &
Used) {
6757 llvm::SmallBitVector &
Used) {
6760 = dyn_cast<TemplateTemplateParmDecl>(
Template)) {
6761 if (TTP->getDepth() == Depth)
6762 Used[TTP->getIndex()] =
true;
6781 llvm::SmallBitVector &
Used) {
6786 if (!T->isDependentType())
6790 switch (T->getTypeClass()) {
6799 case Type::BlockPointer:
6807 case Type::LValueReference:
6808 case Type::RValueReference:
6816 case Type::MemberPointer: {
6822 OnlyDeduced, Depth,
Used);
6826 case Type::DependentSizedArray:
6829 OnlyDeduced, Depth,
Used);
6833 case Type::ConstantArray:
6834 case Type::IncompleteArray:
6835 case Type::ArrayParameter:
6838 OnlyDeduced, Depth,
Used);
6841 case Type::ExtVector:
6844 OnlyDeduced, Depth,
Used);
6847 case Type::DependentVector: {
6855 case Type::DependentSizedExtVector: {
6865 case Type::DependentAddressSpace: {
6869 OnlyDeduced, Depth,
Used);
6872 OnlyDeduced, Depth,
Used);
6876 case Type::ConstantMatrix: {
6883 case Type::DependentSizedMatrix: {
6894 case Type::FunctionProto: {
6898 for (
unsigned I = 0, N = Proto->
getNumParams(); I != N; ++I) {
6903 if (!OnlyDeduced || I + 1 == N ||
6921 case Type::TemplateTypeParm: {
6923 if (TTP->getDepth() == Depth)
6924 Used[TTP->getIndex()] =
true;
6928 case Type::SubstTemplateTypeParmPack: {
6929 const SubstTemplateTypeParmPackType *Subst
6931 if (Subst->getReplacedParameter()->getDepth() == Depth)
6932 Used[Subst->getIndex()] =
true;
6937 case Type::SubstBuiltinTemplatePack: {
6939 OnlyDeduced, Depth,
Used);
6943 case Type::InjectedClassName:
6946 ->getCanonicalTemplateSpecializationType(Ctx);
6949 case Type::TemplateSpecialization: {
6950 const TemplateSpecializationType *Spec
6967 for (
const auto &Arg : Spec->template_arguments())
6976 OnlyDeduced, Depth,
Used);
6983 OnlyDeduced, Depth,
Used);
6986 case Type::DependentName:
6990 OnlyDeduced, Depth,
Used);
6996 OnlyDeduced, Depth,
Used);
6999 case Type::TypeOfExpr:
7003 OnlyDeduced, Depth,
Used);
7006 case Type::Decltype:
7010 OnlyDeduced, Depth,
Used);
7013 case Type::PackIndexing:
7016 OnlyDeduced, Depth,
Used);
7018 OnlyDeduced, Depth,
Used);
7022 case Type::UnaryTransform:
7025 auto Next = UTT->getUnderlyingType();
7027 Next = UTT->getBaseType();
7032 case Type::PackExpansion:
7035 OnlyDeduced, Depth,
Used);
7039 case Type::DeducedTemplateSpecialization:
7042 OnlyDeduced, Depth,
Used);
7044 case Type::DependentBitInt:
7047 OnlyDeduced, Depth,
Used);
7050 case Type::HLSLAttributedResource:
7057 OnlyDeduced, Depth,
Used);
7062 case Type::VariableArray:
7063 case Type::FunctionNoProto:
7066 case Type::ObjCInterface:
7067 case Type::ObjCObject:
7068 case Type::ObjCObjectPointer:
7069 case Type::UnresolvedUsing:
7072 case Type::HLSLInlineSpirv:
7073 case Type::OverflowBehavior:
7074#define TYPE(Class, Base)
7075#define ABSTRACT_TYPE(Class, Base)
7076#define DEPENDENT_TYPE(Class, Base)
7077#define NON_CANONICAL_TYPE(Class, Base) case Type::Class:
7078#include "clang/AST/TypeNodes.inc"
7090 llvm::SmallBitVector &
Used) {
7108 OnlyDeduced, Depth,
Used);
7126 llvm::SmallBitVector &
Used) {
7131 const Expr *E,
unsigned Depth, llvm::SmallBitVector &
Used) {
7132 MarkUsedTemplateParameterVisitor(
Used, Depth,
false)
7133 .TraverseStmt(
const_cast<Expr *
>(E));
7138 bool OnlyDeduced,
unsigned Depth,
7139 llvm::SmallBitVector &
Used) {
7148 for (
unsigned I = 0, N = TemplateArgs.
size(); I != N; ++I)
7155 llvm::SmallBitVector &
Used) {
7156 for (
unsigned I = 0, N = TemplateArgs.size(); I != N; ++I)
7158 false, Depth,
Used);
7163 llvm::SmallBitVector &
Used) {
7164 for (
unsigned I = 0, N = TemplateArgs.size(); I != N; ++I)
7166 false, Depth,
Used);
7171 llvm::SmallBitVector &Deduced) {
7175 Deduced.resize(TemplateParams->
size());
7178 for (
unsigned I = 0, N =
Function->getNumParams(); I != N; ++I)
7180 true, TemplateParams->
getDepth(), Deduced);
7186 if (!T->isDependentType())
7191 llvm::SmallBitVector Deduced(TemplateParams->
size());
7195 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.
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 TemplateDeductionResult DeduceNullPtrTemplateArgument(Sema &S, TemplateParameterList *TemplateParams, NonTypeOrVarTemplateParmDecl NTTP, QualType NullPtrType, TemplateDeductionInfo &Info, bool PartialOrdering, SmallVectorImpl< DeducedTemplateArgument > &Deduced, bool *HasDeducedAnyParam)
Deduce the value of the given non-type template parameter from the given null pointer template argume...
static bool ConvertDeducedTemplateArgument(Sema &S, NamedDecl *Param, DeducedTemplateArgument Arg, NamedDecl *Template, TemplateDeductionInfo &Info, bool IsDeduced, Sema::CheckTemplateArgumentInfo &CTAI)
Convert the given deduced template argument and add it to the set of fully-converted template argumen...
static TemplateDeductionResult DeduceTemplateArguments(Sema &S, TemplateParameterList *TemplateParams, ArrayRef< TemplateArgument > Ps, ArrayRef< TemplateArgument > As, TemplateDeductionInfo &Info, SmallVectorImpl< DeducedTemplateArgument > &Deduced, bool NumberOfArgumentsMustMatch, bool PartialOrdering, PackFold PackFold, bool *HasDeducedAnyParam)
static TemplateDeductionResult DeduceTemplateSpecArguments(Sema &S, TemplateParameterList *TemplateParams, const QualType P, QualType A, TemplateDeductionInfo &Info, bool PartialOrdering, SmallVectorImpl< DeducedTemplateArgument > &Deduced, bool *HasDeducedAnyParam)
static TemplateDeductionResult DeduceTemplateArgumentsByTypeMatch(Sema &S, TemplateParameterList *TemplateParams, QualType Param, QualType Arg, TemplateDeductionInfo &Info, SmallVectorImpl< DeducedTemplateArgument > &Deduced, unsigned TDF, PartialOrderingKind POK, bool DeducedFromArrayBound, bool *HasDeducedAnyParam)
Deduce the template arguments by comparing the parameter type and the argument type (C++ [temp....
static TemplateDeductionResult CheckDeductionConsistency(Sema &S, FunctionTemplateDecl *FTD, UnsignedOrNone ArgIdx, QualType P, QualType A, ArrayRef< TemplateArgument > DeducedArgs, bool CheckConsistency)
static PartialOrderingKind degradeCallPartialOrderingKind(PartialOrderingKind POK)
When propagating a partial ordering kind into a NonCall context, this is used to downgrade a 'Call' i...
static MoreSpecializedTrailingPackTieBreakerResult getMoreSpecializedTrailingPackTieBreaker(const TemplateSpecializationType *TST1, const TemplateSpecializationType *TST2)
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 const Expr * unwrapExpressionForDeduction(const Expr *E)
static bool isSameDeclaration(Decl *X, Decl *Y)
Determine whether two declaration pointers refer to the same declaration.
static NonTypeOrVarTemplateParmDecl getDeducedNTTParameterFromExpr(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 DeduceForEachType(Sema &S, TemplateParameterList *TemplateParams, ArrayRef< QualType > Params, ArrayRef< QualType > Args, TemplateDeductionInfo &Info, SmallVectorImpl< DeducedTemplateArgument > &Deduced, PartialOrderingKind POK, bool FinishingDeduction, T &&DeductFunc)
static TemplateDeductionResult DeduceTemplateBases(Sema &S, const CXXRecordDecl *RD, TemplateParameterList *TemplateParams, QualType P, TemplateDeductionInfo &Info, bool PartialOrdering, SmallVectorImpl< DeducedTemplateArgument > &Deduced, bool *HasDeducedAnyParam)
Attempt to deduce the template arguments by checking the base types according to (C++20 [temp....
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 UnsignedOrNone 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 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 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.
PartialOrderingKind
The kind of PartialOrdering we're performing template argument deduction for (C++11 [temp....
MoreSpecializedTrailingPackTieBreakerResult
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 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 bool isAtLeastAsSpecializedAs(Sema &S, SourceLocation Loc, FunctionTemplateDecl *FT1, FunctionTemplateDecl *FT2, TemplatePartialOrderingContext TPOC, ArrayRef< QualType > Args1, ArrayRef< QualType > Args2, bool Args1Offset)
Determine whether the function template FT1 is at least as specialized as FT2.
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...
PackFold
What directions packs are allowed to match non-packs.
static TemplateDeductionResult ConvertDeducedTemplateArguments(Sema &S, NamedDecl *Template, TemplateParameterList *TemplateParams, bool IsDeduced, SmallVectorImpl< DeducedTemplateArgument > &Deduced, TemplateDeductionInfo &Info, Sema::CheckTemplateArgumentInfo &CTAI, LocalInstantiationScope *CurrentInstantiationScope, unsigned NumAlreadyConverted, bool *IsIncomplete)
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 TemplateDeductionResult CheckDeducedArgumentConstraints(Sema &S, NamedDecl *Template, ArrayRef< TemplateArgument > SugaredDeducedArgs, ArrayRef< TemplateArgument > CanonicalDeducedArgs, TemplateDeductionInfo &Info)
static const TemplateSpecializationType * getLastTemplateSpecType(QualType QT)
Deduce the template arguments by comparing the template parameter type (which is a template-id) with ...
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 TemplateDeductionResult DeduceNonTypeTemplateArgument(Sema &S, TemplateParameterList *TemplateParams, const NonTypeOrVarTemplateParmDecl NTTP, const DeducedTemplateArgument &NewDeduced, QualType ValueType, TemplateDeductionInfo &Info, bool PartialOrdering, SmallVectorImpl< DeducedTemplateArgument > &Deduced, bool *HasDeducedAnyParam)
Deduce the value of the given non-type template parameter as the given deduced template argument.
static bool IsPossiblyOpaquelyQualifiedTypeInternal(const Type *T)
static bool hasDeducibleTemplateParameters(Sema &S, FunctionTemplateDecl *FunctionTemplate, QualType T)
static bool isForwardingReference(QualType Param, unsigned FirstInnerIndex)
Determine whether a type denotes a forwarding reference.
static TemplateDeductionResult FinishTemplateArgumentDeduction(Sema &S, NamedDecl *Entity, TemplateParameterList *EntityTPL, TemplateDecl *Template, bool PartialOrdering, ArrayRef< TemplateArgumentLoc > Ps, ArrayRef< TemplateArgument > As, SmallVectorImpl< DeducedTemplateArgument > &Deduced, TemplateDeductionInfo &Info, bool CopyDeducedArgs)
Complete template argument deduction.
static bool isParameterPack(Expr *PackExpression)
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::TemplateNameKind enum.
Defines the clang::TypeLoc interface and its subclasses.
Allows QualTypes to be sorted and hence used in maps and sets.
static const TemplateArgument & getArgument(const TemplateArgument &A)
C Language Family Type Representation.
SourceLocation getLocation() const
const TemplateTemplateParmDecl * getTemplate() const
bool isExpandedParameterPack() const
const NonTypeTemplateParmDecl * getNTTP() const
unsigned getIndex() const
NonTypeOrVarTemplateParmDecl(const NamedDecl *Template)
TemplateParameter asTemplateParam() const
unsigned getDepth() const
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
TemplateArgument getCanonicalTemplateArgument(const TemplateArgument &Arg) const
Retrieve the "canonical" template argument.
static CanQualType getCanonicalType(QualType T)
Return the canonical (structural) type corresponding to the specified potentially non-canonical type ...
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
QualType getLValueReferenceType(QualType T, bool SpelledAsLValue=true) const
Return the uniqued reference to the type for an lvalue reference to the specified type.
const LangOptions & getLangOpts() const
QualType getDecayedType(QualType T) const
Return the uniqued reference to the decayed version of the given type.
TypeSourceInfo * getTrivialTypeSourceInfo(QualType T, SourceLocation Loc=SourceLocation()) const
Allocate a TypeSourceInfo where all locations have been initialized to a given location,...
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.
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 getMemberPointerType(QualType T, NestedNameSpecifier Qualifier, const CXXRecordDecl *Cls) const
Return the uniqued reference to the type for a member pointer to the specified type in the specified ...
static bool hasSameType(QualType T1, QualType T2)
Determine whether the given types T1 and T2 are equivalent.
QualType getAdjustedParameterType(QualType T) const
Perform adjustment on the parameter type of a function.
QualType getSizeType() const
Return the unique type for "size_t" (C99 7.17), defined in <stddef.h>.
bool hasSameTemplateName(const TemplateName &X, const TemplateName &Y, bool IgnoreDeduced=false) const
Determine whether the given template names refer to the same template.
QualType getAddrSpaceQualType(QualType T, LangAS AddressSpace) const
Return the uniqued reference to the type for an address space qualified type with the specified type ...
CanQualType getCanonicalTagType(const TagDecl *TD) const
bool isSameTemplateArgument(const TemplateArgument &Arg1, const TemplateArgument &Arg2) const
Determine whether the given template arguments Arg1 and Arg2 are equivalent.
static bool hasSameUnqualifiedType(QualType T1, QualType T2)
Determine whether the given types are equivalent after cvr-qualifiers have been removed.
QualType getUnqualifiedArrayType(QualType T, Qualifiers &Quals) const
Return this type as a completely-unqualified array type, capturing the qualifiers in Quals.
TemplateName getDeducedTemplateName(TemplateName Underlying, DefaultArguments DefaultArgs) const
Represents a TemplateName which had some of its default arguments deduced.
const DependentSizedArrayType * getAsDependentSizedArrayType(QualType T) 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.
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.
CanQualType getCanonicalInjectedSpecializationType(const ASTContext &Ctx) const
Retrieve the canonical template specialization type of the injected-class-name for this class templat...
CanQualType getCanonicalInjectedSpecializationType(const ASTContext &Ctx) const
Retrieves the canonical injected specialization type for this partial specialization.
ClassTemplateDecl * getSpecializedTemplate() const
Retrieve the template that this specialization specializes.
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.
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.
ASTContext & getASTContext() const LLVM_READONLY
bool isInvalidDecl() const
SourceLocation getLocation() const
DeclContext * getDeclContext()
virtual Decl * getCanonicalDecl()
Retrieves the "canonical" declaration of the given declaration.
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...
SourceLocation getElaboratedKeywordLoc() const
NestedNameSpecifierLoc getQualifierLoc() const
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 vector type where either the type or size is dependent.
virtual bool TraverseTemplateArgumentLoc(const TemplateArgumentLoc &ArgLoc)
virtual bool TraverseTemplateName(TemplateName Template)
virtual bool TraverseType(QualType T, bool TraverseQualifier=true)
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.
std::optional< llvm::APSInt > getIntegerConstantExpr(const ASTContext &Ctx) const
isIntegerConstantExpr - Return the value if this expression is a valid integer constant expression.
Expr * IgnoreImplicitAsWritten() LLVM_READONLY
Skip past any implicit AST nodes which might surround this expression until reaching a fixed point.
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.
bool hasCXXExplicitFunctionObjectParameter() const
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...
void getAssociatedConstraints(SmallVectorImpl< AssociatedConstraint > &ACs) const
Get the associated-constraints of this function declaration.
const TemplateArgumentList * getTemplateSpecializationArgs() const
Retrieve the template arguments used to produce this function template specialization from the primar...
bool isImmediateEscalating() const
OverloadedOperatorKind getOverloadedOperator() const
getOverloadedOperator - Which C++ overloaded operator this function represents, if any.
size_t param_size() const
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.
Qualifiers getMethodQuals() const
QualType getParamType(unsigned i) const
bool hasExceptionSpec() const
Return whether this function has any kind of exception spec.
bool isVariadic() const
Whether this function prototype is variadic.
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
RefQualifierKind getRefQualifier() const
Retrieve the ref-qualifier associated with this function type.
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)
Describes an C or C++ initializer list.
unsigned getNumInits() const
unsigned getNumInitsWithEmbedExpanded() const
getNumInits but if the list has an EmbedExpr inside includes full length of embedded data.
ArrayRef< Expr * > inits()
An lvalue reference type, per C++11 [dcl.ref].
A stack-allocated class that identifies which local variable declaration instantiations are present i...
NamedDecl * getPartiallySubstitutedPack(const TemplateArgument **ExplicitArgs=nullptr, unsigned *NumExplicitArgs=nullptr) const
Retrieve the partially-substitued template parameter pack.
void ResetPartiallySubstitutedPack()
Reset the partially-substituted pack when it is no longer of interest.
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.
NestedNameSpecifier getQualifier() const
QualType getPointeeType() const
Data structure that captures multiple levels of template argument lists for use in template instantia...
void addOuterRetainedLevels(unsigned Num)
void replaceInnermostTemplateArguments(Decl *AssociatedDecl, ArgList Args, bool Final=false)
Replaces the current 'innermost' level with the provided argument list.
This represents a decl that may have a name.
NamedDecl * getUnderlyingDecl()
Looks through UsingDecls and ObjCCompatibleAliasDecls for the underlying named decl.
DeclarationName getDeclName() const
Get the actual, stored name of the declaration, which may be a special name.
Class that aids in the construction of nested-name-specifiers along with source-location information ...
Represents a C++ nested name specifier, such as "\::std::vector<int>::".
const Type * getAsType() const
@ Type
A type, stored as a Type*.
NonTypeTemplateParmDecl - Declares a non-type template parameter, e.g., "Size" in.
Represents a pointer to an Objective C object.
A reference to an overloaded function set, either an UnresolvedLookupExpr or an UnresolvedMemberExpr.
bool isVarDeclReference() const
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
TemplateTemplateParmDecl * getTemplateTemplateDecl() const
void copyTemplateArgumentsInto(TemplateArgumentListInfo &List) const
Copies the template arguments into the given structure.
bool isConceptReference() const
decls_iterator decls_end() const
ArrayRef< TemplateArgumentLoc > template_arguments() const
Represents a C++11 pack expansion that produces a sequence of expressions.
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.
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 compatiblyIncludes(Qualifiers other, const ASTContext &Ctx) const
Determines if these qualifiers compatibly include another set.
bool hasAddressSpace() const
void removeAddressSpace()
bool hasObjCGCAttr() const
void setCVRQualifiers(unsigned mask)
bool hasObjCLifetime() const
ObjCLifetime getObjCLifetime() const
Qualifiers withoutObjCLifetime() const
LangAS getAddressSpace() const
void setObjCLifetime(ObjCLifetime type)
An rvalue reference type, per C++11 [dcl.ref].
ArrayRef< TemplateArgument > getInjectedTemplateArgs(const ASTContext &Context) const
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)
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 TryFunctionConversion(QualType FromType, QualType ToType, QualType &ResultTy) const
Same as IsFunctionConversion, but if this would return true, it sets ResultTy to ToType.
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.
ClassTemplatePartialSpecializationDecl * getMoreSpecializedPartialSpecialization(ClassTemplatePartialSpecializationDecl *PS1, ClassTemplatePartialSpecializationDecl *PS2, SourceLocation Loc)
Returns the more specialized class template partial specialization according to the rules of partial ...
const ExpressionEvaluationContextRecord & currentEvaluationContext() const
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...
TemplateDeductionResult FinishTemplateArgumentDeduction(FunctionTemplateDecl *FunctionTemplate, SmallVectorImpl< DeducedTemplateArgument > &Deduced, unsigned NumExplicitlySpecified, FunctionDecl *&Specialization, sema::TemplateDeductionInfo &Info, SmallVectorImpl< OriginalCallArg > const *OriginalCallArgs, bool PartialOverloading, bool PartialOrdering, bool ForOverloadSetAddressResolution, llvm::function_ref< bool(bool)> CheckNonDependent=[](bool) { return false;})
Finish template argument deduction for a function template, checking the deduced template arguments f...
@ 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...
void MarkUsedTemplateParametersForSubsumptionParameterMapping(const Expr *E, unsigned Depth, llvm::SmallBitVector &Used)
Mark which template parameters are named in a given expression.
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.
bool isTemplateTemplateParameterAtLeastAsSpecializedAs(TemplateParameterList *PParam, TemplateDecl *PArg, TemplateDecl *AArg, const DefaultArguments &DefaultArgs, SourceLocation ArgLoc, bool PartialOrdering, bool *StrictPackMatch)
PrintingPolicy getPrintingPolicy() const
Retrieve a suitable printing policy for diagnostics.
bool SubstTemplateArguments(ArrayRef< TemplateArgumentLoc > Args, const MultiLevelTemplateArgumentList &TemplateArgs, TemplateArgumentListInfo &Outputs)
bool CheckConstraintSatisfaction(ConstrainedDeclOrNestedRequirement Entity, ArrayRef< AssociatedConstraint > AssociatedConstraints, const MultiLevelTemplateArgumentList &TemplateArgLists, SourceRange TemplateIDRange, ConstraintSatisfaction &Satisfaction, const ConceptReference *TopLevelConceptId=nullptr, Expr **ConvertedExpr=nullptr)
Check whether the given list of constraint expressions are satisfied (as if in a 'conjunction') given...
@ TPL_TemplateParamsEquivalent
We are determining whether the template-parameters are equivalent according to C++ [temp....
bool CheckTemplateArgument(NamedDecl *Param, TemplateArgumentLoc &Arg, NamedDecl *Template, SourceLocation TemplateLoc, SourceLocation RAngleLoc, unsigned ArgumentPackIndex, CheckTemplateArgumentInfo &CTAI, CheckTemplateArgumentKind CTAK)
Check that the given template argument corresponds to the given template parameter.
bool isSameOrCompatibleFunctionType(QualType Param, QualType Arg)
Compare types for equality with respect to possibly compatible function types (noreturn adjustment,...
const LangOptions & getLangOpts() const
UnsignedOrNone 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
void DiagnoseUnsatisfiedConstraint(const ConstraintSatisfaction &Satisfaction, SourceLocation Loc={}, bool First=true)
Emit diagnostics explaining why a constraint expression was deemed unsatisfied.
bool IsDerivedFrom(SourceLocation Loc, CXXRecordDecl *Derived, CXXRecordDecl *Base, CXXBasePaths &Paths)
Determine whether the type Derived is a C++ class that is derived from the type Base.
bool isUnevaluatedContext() const
Determines whether we are currently in a context that is not evaluated as per C++ [expr] p5.
FunctionDecl * ResolveSingleFunctionTemplateSpecialization(OverloadExpr *ovl, bool Complain=false, DeclAccessPair *Found=nullptr, TemplateSpecCandidateSet *FailedTSC=nullptr, bool ForTypeDeduction=false)
Given an expression that refers to an overloaded function, try to resolve that overloaded function ex...
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)
TemplateArgumentLoc SubstDefaultTemplateArgumentIfAvailable(TemplateDecl *Template, SourceLocation TemplateKWLoc, SourceLocation TemplateNameLoc, 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...
TypeSourceInfo * SubstAutoTypeSourceInfoDependent(TypeSourceInfo *TypeWithAuto)
TypeSourceInfo * ReplaceAutoTypeSourceInfo(TypeSourceInfo *TypeWithAuto, QualType Replacement)
bool isSFINAEContext() const
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.
@ PotentiallyEvaluated
The current expression is potentially evaluated at run time, which means that code may be generated t...
@ Unevaluated
The current expression and its subexpressions occur within an unevaluated operand (C++11 [expr]p7),...
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.
bool IsAtLeastAsConstrained(const NamedDecl *D1, MutableArrayRef< AssociatedConstraint > AC1, const NamedDecl *D2, MutableArrayRef< AssociatedConstraint > AC2, bool &Result)
Check whether the given declaration's associated constraints are at least as constrained than another...
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)
bool CheckFunctionTemplateConstraints(SourceLocation PointOfInstantiation, FunctionDecl *Decl, ArrayRef< TemplateArgument > TemplateArgs, ConstraintSatisfaction &Satisfaction)
void runWithSufficientStackSpace(SourceLocation Loc, llvm::function_ref< void()> Fn)
Run some code with "sufficient" stack space.
bool isMoreSpecializedThanPrimary(ClassTemplatePartialSpecializationDecl *T, sema::TemplateDeductionInfo &Info)
bool IsFunctionConversion(QualType FromType, QualType ToType) const
Determine whether the conversion from FromType to ToType is a valid conversion of ExtInfo/ExtProtoInf...
std::string getTemplateArgumentBindingsText(const TemplateParameterList *Params, const TemplateArgumentList &Args)
Produces a formatted string that describes the binding of template parameters to template arguments.
bool CheckTemplateArgumentList(TemplateDecl *Template, SourceLocation TemplateLoc, TemplateArgumentListInfo &TemplateArgs, const DefaultArguments &DefaultArgs, bool PartialTemplateArgs, CheckTemplateArgumentInfo &CTAI, bool UpdateArgsWithConversions=true, bool *ConstraintsNotSatisfied=nullptr)
Check that the given template arguments can be provided to the given template, converting the argumen...
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.
@ 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.
FunctionTemplateDecl * getMoreSpecializedTemplate(FunctionTemplateDecl *FT1, FunctionTemplateDecl *FT2, SourceLocation Loc, TemplatePartialOrderingContext TPOC, unsigned NumCallArguments1, QualType RawObj1Ty={}, QualType RawObj2Ty={}, bool Reversed=false, bool PartialOverloading=false)
Returns the more specialized function template according to the rules of function template partial or...
void MarkDeducedTemplateParameters(const FunctionTemplateDecl *FunctionTemplate, llvm::SmallBitVector &Deduced)
NamedDecl * getPack() const
Retrieve the parameter pack.
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.
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.
const TemplateArgument * pack_iterator
Iterator that traverses the elements 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.).
void getAssociatedConstraints(llvm::SmallVectorImpl< AssociatedConstraint > &AC) const
Get the total constraint-expression associated with this template, including constraint-expressions d...
SourceRange getSourceRange() const override LLVM_READONLY
Source range that this declaration covers.
TemplateParameterList * getTemplateParameters() const
Get the list of template parameters.
Represents a C++ template name within the type system.
TemplateDecl * getAsTemplateDecl(bool IgnoreDeduced=false) 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.
Stores a list of template parameters for a TemplateDecl and its derived classes.
NamedDecl * getParam(unsigned Idx)
ArrayRef< TemplateArgument > getInjectedTemplateArgs(const ASTContext &Context)
Get the template argument list of the template parameter list.
unsigned getDepth() const
Get the depth of this template parameter list in the set of template parameter lists.
SourceLocation getRAngleLoc() const
SourceLocation getLAngleLoc() const
ArrayRef< NamedDecl * > asArray()
SourceLocation getTemplateLoc() const
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...
TemplateTemplateParmDecl - Declares a template template parameter, e.g., "T" in.
TemplateNameKind templateParameterKind() const
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.
bool isExpandedParameterPack() const
Whether this parameter is a template template parameter pack that has a known list of different templ...
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, UnsignedOrNone NumExpanded=std::nullopt)
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.
QualType getType() const
Return the type wrapped by this type source info.
SourceLocation getNameLoc() const
void setNameLoc(SourceLocation Loc)
The base class of the type hierarchy.
const TemplateSpecializationType * getAsNonAliasTemplateSpecializationType() const
Look through sugar for an instance of TemplateSpecializationType which is not a type alias,...
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
CXXRecordDecl * getAsCXXRecordDecl() const
Retrieves the CXXRecordDecl that this type refers to, either because the type is a RecordType or beca...
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 isMemberFunctionPointerType() const
const T * getAsCanonical() const
If this type is canonically the specified type, return its canonical type cast to that specified type...
bool isAnyPointerType() const
TypeClass getTypeClass() const
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.
VarTemplateDecl * getCanonicalDecl() override
Retrieves the canonical declaration of this template.
const TemplateArgumentList & getTemplateArgs() const
Retrieve the template arguments of the variable template specialization.
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.
void setStrictPackMatch()
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.
bool hasStrictPackMatch() const
__inline void unsigned int _2
The JSON file list parser is used to communicate input to InstallAPI.
@ OO_None
Not an overloaded operator.
@ Match
This is not an overload because the signature exactly matches an existing declaration.
bool isa(CodeGen::Address addr)
bool isTargetAddressSpace(LangAS AS)
@ Specialization
We are substituting template parameters for template arguments in order to form a template specializa...
@ Both
Look for allocation functions in both the global scope and in the scope of the allocated class.
@ RQ_None
No ref-qualifier was provided.
@ RQ_RValue
An rvalue ref-qualifier was provided (&&).
@ TemplateName
The identifier is a template name. FIXME: Add an annotation for that.
NamedDecl * getAsNamedDecl(TemplateParameter P)
bool isPackProducingBuiltinTemplateName(TemplateName N)
UnsignedOrNone getExpandedPackSize(const NamedDecl *Param)
Check whether the template parameter is a pack expansion, and if so, determine the number of paramete...
unsigned toTargetAddressSpace(LangAS AS)
bool isLambdaCallOperator(const CXXMethodDecl *MD)
@ Result
The result type of a method or function.
std::pair< unsigned, unsigned > getDepthAndIndex(const NamedDecl *ND)
Retrieve the depth and index of a template parameter.
@ Template
We are parsing a template declaration.
ActionResult< CXXBaseSpecifier * > BaseResult
@ FunctionTemplate
The name was classified as a function template name.
@ Concept
The name was classified as a concept name.
bool isLambdaConversionOperator(CXXConversionDecl *C)
@ TNK_Var_template
The name refers to a variable template whose specialization produces a variable.
@ TNK_Concept_template
The name refers to a concept.
llvm::PointerUnion< TemplateTypeParmDecl *, NonTypeTemplateParmDecl *, TemplateTemplateParmDecl * > TemplateParameter
Stores a template parameter of any kind.
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.
DynamicRecursiveASTVisitorBase< false > DynamicRecursiveASTVisitor
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.
@ CUDATargetMismatch
CUDA Target attributes do not match.
@ 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.
U cast(CodeGen::Address addr)
@ None
The alignment was not explicit in code.
@ Noexcept
Condition in a noexcept(bool) specifier.
@ None
No keyword precedes the qualified type name.
ActionResult< Expr * > ExprResult
@ 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...
static constexpr bool value
static constexpr bool value
static constexpr bool value
A pack that we're currently deducing.
DeducedPack(unsigned Index)
SmallVector< DeducedTemplateArgument, 4 > New
DeducedTemplateArgument Saved
DeducedTemplateArgument DeferredDeduction
ExceptionSpecificationType Type
The kind of exception specification this is.
Extra information about a function prototype.
const ExtParameterInfo * ExtParameterInfos
bool StrictPackMatch
Is set to true when, in the context of TTP matching, a pack parameter matches non-pack arguments.
bool MatchingTTP
If true, assume these template arguments are the injected template arguments for a template template ...
bool PartialOrdering
The check is being performed in the context of partial ordering.
SmallVector< TemplateArgument, 4 > SugaredConverted
The checked, converted argument will be added to the end of these vectors.
SmallVector< TemplateArgument, 4 > CanonicalConverted
@ 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 ...
bool isPotentiallyEvaluated() const
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.