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)
251 if (
const auto *DTI = dyn_cast<DependentTemplateIdExpr>(E))
252 if (!DTI->getTemplateName().getAsPackIndexingTemplate() &&
253 DTI->getParameter()->getDepth() == Depth)
254 return DTI->getParameter();
268 X = NX->getUnderlyingDecl();
269 if (
NamedDecl *NY = dyn_cast<NamedDecl>(Y))
270 Y = NY->getUnderlyingDecl();
283 bool AggregateCandidateDeduction =
false) {
296 QualType XType =
X.getNonTypeTemplateArgumentType();
299 if (YType.
isNull() || !Context.hasSameType(XType, YType))
304 switch (
X.getKind()) {
306 llvm_unreachable(
"Non-deduced template arguments handled above");
313 X.wasDeducedFromArrayBound() ||
319 return X.wasDeducedFromArrayBound() ? Y :
X;
333 return X.wasDeducedFromArrayBound() ? Y :
X;
342 X.structurallyEquals(Y)))
350 Context.hasSameTemplateName(
X.getAsTemplate(), Y.
getAsTemplate()))
358 Context.hasSameTemplateName(
X.getAsTemplateOrTemplatePattern(),
370 llvm::FoldingSetNodeID ID1, ID2;
371 X.getAsExpr()->Profile(ID1, Context,
true);
374 return X.wasDeducedFromArrayBound() ? Y :
X;
381 assert(!
X.wasDeducedFromArrayBound());
394 X.getParamTypeForDecl());
431 (!AggregateCandidateDeduction &&
X.pack_size() != Y.
pack_size()))
443 if (Merged.isNull() && !(XA->isNull() && YA->isNull()))
445 NewPack.push_back(Merged);
448 NewPack.push_back(*XA);
458 llvm_unreachable(
"Invalid TemplateArgument Kind!");
471 bool *HasDeducedAnyParam) {
473 "deducing non-type template argument with wrong depth");
497 if (
auto *Expansion = dyn_cast<PackExpansionType>(ParamType))
498 ParamType = Expansion->getPattern();
504 ValueType = ValueType.getNonReferenceType();
511 S, TemplateParams, ParamType, ValueType, Info,
Deduced,
525 bool *HasDeducedAnyParam) {
527 S, TemplateParams, NTTP,
529 DeducedFromArrayBound),
541 bool *HasDeducedAnyParam) {
563 bool *HasDeducedAnyParam) {
579 bool *HasDeducedAnyParam) {
591 bool *HasDeducedAnyParam) {
599 if (
auto *TempParam = dyn_cast<TemplateTemplateParmDecl>(ParamDecl)) {
606 unsigned StartPos = 0;
623 Arg, {StartPos, DefaultArguments.drop_front(StartPos)}))
629 Info.
Param = TempParam;
636 if (HasDeducedAnyParam)
637 *HasDeducedAnyParam =
true;
672 const TemplateSpecializationType *LastTST =
nullptr;
674 const TemplateSpecializationType *TST =
675 T->getAs<TemplateSpecializationType>();
678 if (!TST->isSugared())
681 T = TST->desugar().getTypePtr();
690 bool *HasDeducedAnyParam) {
695 TNP = TP->getTemplateName();
704 TP->castAsCanonical<TemplateSpecializationType>()->template_arguments();
706 const auto *TT = P->
castAs<InjectedClassNameType>();
707 TNP = TT->getTemplateName(S.
Context);
708 PResolved = TT->getTemplateArgs(S.
Context);
730 SA->getCanonicalTypeInternal()
731 ->castAs<TemplateSpecializationType>()
732 ->template_arguments();
746 S, TemplateParams, PResolved, AResolved, Info,
Deduced,
754 const auto *TA = A->
getAs<TagType>();
760 TNA = TST->getTemplateName();
762 TNA = TA->getTemplateName(S.
Context);
781 S, TemplateParams, PResolved, AResolved, Info,
Deduced,
787 assert(
T->isCanonicalUnqualified());
789 switch (
T->getTypeClass()) {
790 case Type::TypeOfExpr:
792 case Type::DependentName:
794 case Type::PackIndexing:
795 case Type::UnresolvedUsing:
796 case Type::TemplateTypeParm:
800 case Type::ConstantArray:
801 case Type::IncompleteArray:
802 case Type::VariableArray:
803 case Type::DependentSizedArray:
816 T->getCanonicalTypeInternal().getTypePtr());
854class PackDeductionScope {
862 bool DeducePackIfNotAlreadyDeduced =
false,
863 bool FinishingDeduction =
false)
864 : S(S), TemplateParams(TemplateParams),
Deduced(
Deduced), Info(Info),
865 DeducePackIfNotAlreadyDeduced(DeducePackIfNotAlreadyDeduced),
866 FinishingDeduction(FinishingDeduction) {
867 unsigned NumNamedPacks = addPacks(Pattern);
868 finishConstruction(NumNamedPacks);
872 PackDeductionScope(Sema &S, TemplateParameterList *TemplateParams,
873 SmallVectorImpl<DeducedTemplateArgument> &Deduced,
874 TemplateDeductionInfo &Info,
unsigned Index)
875 : S(S), TemplateParams(TemplateParams), Deduced(Deduced), Info(Info) {
877 finishConstruction(1);
881 void addPack(
unsigned Index) {
884 DeducedFromEarlierParameter = !Deduced[Index].isNull();
885 DeducedPack Pack(Index);
886 if (!FinishingDeduction) {
887 Pack.Saved = Deduced[Index];
888 Deduced[Index] = TemplateArgument();
896 FixedNumExpansions = ExpandedPackExpansions;
898 Packs.push_back(Pack);
901 unsigned addPacks(TemplateArgument Pattern) {
904 llvm::SmallBitVector SawIndices(TemplateParams->size());
905 llvm::SmallVector<TemplateArgument, 4> ExtraDeductions;
907 auto AddPack = [&](
unsigned Index) {
908 if (SawIndices[Index])
910 SawIndices[Index] =
true;
917 if (
auto *NTTP = dyn_cast<NonTypeTemplateParmDecl>(
918 TemplateParams->getParam(Index))) {
919 if (!NTTP->isExpandedParameterPack())
922 if (
auto *Expansion = dyn_cast<PackExpansionType>(
923 S.Context.getUnconstrainedType(NTTP->getType())))
924 ExtraDeductions.push_back(Expansion->getPattern());
930 auto Collect = [&](TemplateArgument Pattern) {
931 SmallVector<UnexpandedParameterPack, 2> Unexpanded;
932 S.collectUnexpandedParameterPacks(Pattern, Unexpanded);
933 for (
unsigned I = 0, N = Unexpanded.size(); I != N; ++I) {
934 unsigned Depth, Index;
937 if (isa_and_present<ParmVarDecl>(
938 dyn_cast<NamedDecl *>(Unexpanded[I].first)))
941 std::tie(Depth, Index) = *DI;
945 if (Depth == Info.getDeducedDepth())
953 unsigned NumNamedPacks = Packs.size();
957 while (!ExtraDeductions.empty())
958 Collect(ExtraDeductions.pop_back_val());
960 return NumNamedPacks;
963 void finishConstruction(
unsigned NumNamedPacks) {
965 const TemplateArgument *PartialPackArgs =
nullptr;
966 unsigned NumPartialPackArgs = 0;
967 std::pair<unsigned, unsigned> PartialPackDepthIndex(-1u, -1u);
968 if (
auto *Scope = S.CurrentInstantiationScope)
969 if (
auto *Partial = Scope->getPartiallySubstitutedPack(
970 &PartialPackArgs, &NumPartialPackArgs))
976 bool IsExpanded =
true;
977 for (
unsigned I = 0; I != NumNamedPacks; ++I) {
978 if (Packs[I].Index >= Info.getNumExplicitArgs()) {
980 IsPartiallyExpanded =
false;
983 if (PartialPackDepthIndex ==
984 std::make_pair(Info.getDeducedDepth(), Packs[I].Index)) {
985 IsPartiallyExpanded =
true;
993 if (IsPartiallyExpanded)
994 PackElements += NumPartialPackArgs;
995 else if (IsExpanded && FixedNumExpansions)
996 PackElements += *FixedNumExpansions;
998 for (
auto &Pack : Packs) {
999 if (Info.PendingDeducedPacks.size() > Pack.Index)
1000 Pack.Outer = Info.PendingDeducedPacks[Pack.Index];
1002 Info.PendingDeducedPacks.resize(Pack.Index + 1);
1003 Info.PendingDeducedPacks[Pack.Index] = &Pack;
1005 if (PartialPackDepthIndex ==
1006 std::make_pair(Info.getDeducedDepth(), Pack.Index)) {
1007 Pack.New.append(PartialPackArgs, PartialPackArgs + NumPartialPackArgs);
1013 ~PackDeductionScope() {
1014 for (
auto &Pack : Packs)
1015 Info.PendingDeducedPacks[Pack.Index] = Pack.Outer;
1020 unsigned PackSize = Packs[0].Saved.pack_size();
1022 if (std::all_of(Packs.begin() + 1, Packs.end(), [&PackSize](
const auto &P) {
1023 return P.Saved.pack_size() == PackSize;
1026 return std::nullopt;
1031 bool isDeducedFromEarlierParameter()
const {
1032 return DeducedFromEarlierParameter;
1037 bool isPartiallyExpanded() {
return IsPartiallyExpanded; }
1042 bool hasFixedArity() {
return static_cast<bool>(FixedNumExpansions); }
1047 bool hasNextElement() {
1048 return !FixedNumExpansions || *FixedNumExpansions > PackElements;
1052 void nextPackElement() {
1056 if (!FinishingDeduction) {
1057 for (
auto &Pack : Packs) {
1058 DeducedTemplateArgument &DeducedArg = Deduced[Pack.Index];
1059 if (!Pack.New.empty() || !DeducedArg.
isNull()) {
1060 while (Pack.New.size() < PackElements)
1061 Pack.New.push_back(DeducedTemplateArgument());
1062 if (Pack.New.size() == PackElements)
1063 Pack.New.push_back(DeducedArg);
1065 Pack.New[PackElements] = DeducedArg;
1066 DeducedArg = Pack.New.size() > PackElements + 1
1067 ? Pack.New[PackElements + 1]
1068 : DeducedTemplateArgument();
1079 if (FinishingDeduction)
1080 return TemplateDeductionResult::Success;
1083 for (
auto &Pack : Packs) {
1085 if (!FinishingDeduction)
1086 Deduced[Pack.Index] = Pack.Saved;
1101 Pack.New.resize(PackElements);
1104 DeducedTemplateArgument NewPack;
1105 if (Pack.New.empty()) {
1109 TemplateArgument *ArgumentPack =
1110 new (S.Context) TemplateArgument[Pack.New.size()];
1111 std::copy(Pack.New.begin(), Pack.New.end(), ArgumentPack);
1112 NewPack = DeducedTemplateArgument(
1113 TemplateArgument(llvm::ArrayRef(ArgumentPack, Pack.New.size())),
1119 Pack.New[0].wasDeducedFromArrayBound());
1123 DeducedTemplateArgument *Loc;
1125 if (Pack.Outer->DeferredDeduction.isNull()) {
1128 Pack.Outer->DeferredDeduction = NewPack;
1131 Loc = &Pack.Outer->DeferredDeduction;
1133 Loc = &Deduced[Pack.Index];
1137 DeducedTemplateArgument OldPack = *Loc;
1139 S.Context, OldPack, NewPack, DeducePackIfNotAlreadyDeduced);
1141 Info.AggregateDeductionCandidateHasMismatchedArity =
1147 if (!
Result.isNull() && !Pack.DeferredDeduction.isNull()) {
1149 NewPack = Pack.DeferredDeduction;
1153 NamedDecl *Param = TemplateParams->getParam(Pack.Index);
1156 Info.FirstArg = OldPack;
1157 Info.SecondArg = NewPack;
1158 return TemplateDeductionResult::Inconsistent;
1164 if (*Expansions != PackElements) {
1167 return TemplateDeductionResult::IncompletePack;
1174 return TemplateDeductionResult::Success;
1179 TemplateParameterList *TemplateParams;
1180 SmallVectorImpl<DeducedTemplateArgument> &Deduced;
1181 TemplateDeductionInfo &Info;
1182 unsigned PackElements = 0;
1183 bool IsPartiallyExpanded =
false;
1184 bool DeducePackIfNotAlreadyDeduced =
false;
1185 bool DeducedFromEarlierParameter =
false;
1186 bool FinishingDeduction =
false;
1190 SmallVector<DeducedPack, 2> Packs;
1200 bool FinishingDeduction,
T &&DeductFunc) {
1209 const PackExpansionType *Expansion
1210 = dyn_cast<PackExpansionType>(Params[
ParamIdx]);
1215 if (ArgIdx >= Args.size())
1227 DeductFunc(S, TemplateParams,
ParamIdx, ArgIdx,
1228 Params[
ParamIdx].getUnqualifiedType(),
1229 Args[ArgIdx].getUnqualifiedType(), Info,
Deduced, POK);
1244 QualType Pattern = Expansion->getPattern();
1245 PackDeductionScope PackScope(S, TemplateParams,
Deduced, Info, Pattern,
1247 FinishingDeduction);
1251 if (
ParamIdx + 1 == Params.size() || PackScope.hasFixedArity()) {
1252 for (; ArgIdx < Args.size() && PackScope.hasNextElement(); ++ArgIdx) {
1255 S, TemplateParams,
ParamIdx, ArgIdx,
1260 PackScope.nextPackElement();
1281 if (NumExpansions && !PackScope.isPartiallyExpanded()) {
1282 for (
unsigned I = 0; I != *NumExpansions && ArgIdx < Args.size();
1284 PackScope.nextPackElement();
1290 if (
auto Result = PackScope.finish();
1306 if (ArgIdx < Args.size())
1349 llvm::SmallBitVector *HasDeducedParam) {
1350 return ::DeduceForEachType(
1351 S, TemplateParams, Params, Args, Info,
Deduced, POK,
1357 bool HasDeducedAnyParamCopy =
false;
1359 S, TemplateParams, P, A, Info,
Deduced, TDF, POK,
1360 false, &HasDeducedAnyParamCopy);
1361 if (HasDeducedAnyParam && HasDeducedAnyParamCopy)
1362 *HasDeducedAnyParam =
true;
1363 if (HasDeducedParam && HasDeducedAnyParamCopy)
1364 (*HasDeducedParam)[
ParamIdx] =
true;
1378 if (ParamQs == ArgQs)
1406 return Context.hasSameType(P, A);
1413 return Context.hasSameFunctionTypeIgnoringExceptionSpec(P, A);
1422 if (!Guide || !Guide->isImplicit())
1424 return Guide->getDeducedTemplate()->getTemplateParameters()->size();
1434 if (ParamRef->getPointeeType().getQualifiers())
1437 ParamRef->getPointeeType()->getAsCanonical<TemplateTypeParmType>();
1438 return TypeParm && TypeParm->getIndex() >= FirstInnerIndex;
1466 bool *HasDeducedAnyParam) {
1492 bool HasDeducedAnyParam;
1494 llvm::MapVector<const CXXRecordDecl *, MatchValue> Matches;
1496 auto AddBases = [&Visited, &ToVisit](
const CXXRecordDecl *RD) {
1499 assert(
T->isRecordType() &&
"Base class that isn't a record?");
1500 if (Visited.insert(
T->getAsCXXRecordDecl()).second)
1501 ToVisit.push_back(
T);
1510 while (!ToVisit.empty()) {
1511 QualType NextT = ToVisit.pop_back_val();
1516 bool HasDeducedAnyParamCopy =
false;
1519 &HasDeducedAnyParamCopy);
1525 Matches.insert({RD, {DeducedCopy, HasDeducedAnyParamCopy}});
1536 if (Matches.size() > 1) {
1538 for (
const auto &
Match : Matches)
1539 AddBases(
Match.first);
1543 while (Matches.size() > 1 && !ToVisit.empty()) {
1544 const CXXRecordDecl *RD = ToVisit.pop_back_val()->getAsCXXRecordDecl();
1553 if (Matches.empty())
1555 if (Matches.size() > 1)
1558 std::swap(Matches.front().second.Deduced,
Deduced);
1559 if (
bool HasDeducedAnyParamCopy = Matches.front().second.HasDeducedAnyParam;
1560 HasDeducedAnyParamCopy && HasDeducedAnyParam)
1561 *HasDeducedAnyParam = HasDeducedAnyParamCopy;
1602 bool *HasDeducedAnyParam) {
1606 if (
const auto *AExp = dyn_cast<PackExpansionType>(A))
1607 A = AExp->getPattern();
1702 if (
const auto *TTP = P->
getAsCanonical<TemplateTypeParmType>()) {
1708 unsigned Index = TTP->getIndex();
1735 "saw template type parameter with wrong depth");
1737 "Unresolved overloaded function");
1780 case Decl::TemplateTypeParm:
1783 case Decl::NonTypeTemplateParm:
1786 case Decl::TemplateTemplateParm:
1790 llvm_unreachable(
"unexpected kind");
1798 if (HasDeducedAnyParam)
1799 *HasDeducedAnyParam =
true;
1811 if (P->
getAs<SubstTemplateTypeParmPackType>())
1857#define NON_CANONICAL_TYPE(Class, Base) \
1858 case Type::Class: llvm_unreachable("deducing non-canonical type: " #Class);
1859#define TYPE(Class, Base)
1860#include "clang/AST/TypeNodes.inc"
1862 case Type::TemplateTypeParm:
1863 case Type::SubstTemplateTypeParmPack:
1864 case Type::SubstBuiltinTemplatePack:
1865 llvm_unreachable(
"Type nodes handled above");
1877 case Type::VariableArray:
1879 case Type::FunctionNoProto:
1882 case Type::ObjCObject:
1883 case Type::ObjCInterface:
1884 case Type::ObjCObjectPointer:
1894 case Type::Complex: {
1899 S, TemplateParams, CP->getElementType(), CA->getElementType(), Info,
1901 false, HasDeducedAnyParam);
1905 case Type::Atomic: {
1910 S, TemplateParams, PA->getValueType(), AA->getValueType(), Info,
1912 false, HasDeducedAnyParam);
1916 case Type::Pointer: {
1930 false, HasDeducedAnyParam);
1934 case Type::LValueReference: {
1941 S, TemplateParams, RP->getPointeeType(), RA->getPointeeType(), Info,
1943 false, HasDeducedAnyParam);
1947 case Type::RValueReference: {
1954 S, TemplateParams, RP->getPointeeType(), RA->getPointeeType(), Info,
1956 false, HasDeducedAnyParam);
1960 case Type::IncompleteArray: {
1966 assert(IAP &&
"Template parameter not of incomplete array type");
1969 S, TemplateParams, IAP->getElementType(), IAA->getElementType(), Info,
1972 false, HasDeducedAnyParam);
1976 case Type::ConstantArray: {
1980 if (!CAA || CAA->getSize() != CAP->getSize())
1984 S, TemplateParams, CAP->getElementType(), CAA->getElementType(), Info,
1987 false, HasDeducedAnyParam);
1991 case Type::DependentSizedArray: {
2000 S, TemplateParams, DAP->getElementType(), AA->getElementType(),
2003 false, HasDeducedAnyParam);
2016 "saw non-type template parameter with wrong depth");
2017 if (
const auto *CAA = dyn_cast<ConstantArrayType>(AA)) {
2018 llvm::APSInt Size(CAA->getSize());
2024 if (
const auto *DAA = dyn_cast<DependentSizedArrayType>(AA))
2025 if (DAA->getSizeExpr())
2027 S, TemplateParams, NTTP, DAA->getSizeExpr(), Info,
2037 case Type::FunctionProto: {
2043 if (FPP->getMethodQuals() != FPA->getMethodQuals() ||
2044 FPP->getRefQualifier() != FPA->getRefQualifier() ||
2045 FPP->isVariadic() != FPA->isVariadic())
2050 S, TemplateParams, FPP->getReturnType(), FPA->getReturnType(),
2052 false, HasDeducedAnyParam);
2058 S, TemplateParams, FPP->param_types(), FPA->param_types(), Info,
2071 Expr *NoexceptExpr = FPP->getNoexceptExpr();
2076 "saw non-type template parameter with wrong depth");
2079 switch (FPA->canThrow()) {
2093 if (
Expr *ArgNoexceptExpr = FPA->getNoexceptExpr())
2095 S, TemplateParams, NTTP, ArgNoexceptExpr, Info,
2109 case Type::InjectedClassName:
2118 case Type::TemplateSpecialization: {
2165 case Type::MemberPointer: {
2182 S, TemplateParams, PPT, APT, Info,
Deduced, SubTDF,
2184 false, HasDeducedAnyParam);
2191 :
QualType(MPP->getQualifier().getAsType(), 0);
2192 assert(!TP.
isNull() &&
"member pointer with non-type class");
2197 :
QualType(MPA->getQualifier().getAsType(), 0)
2199 assert(!TA.
isNull() &&
"member pointer with non-type class");
2202 S, TemplateParams, TP, TA, Info,
Deduced, SubTDF,
2204 false, HasDeducedAnyParam);
2212 case Type::BlockPointer: {
2218 S, TemplateParams, BPP->getPointeeType(), BPA->getPointeeType(), Info,
2220 false, HasDeducedAnyParam);
2226 case Type::ExtVector: {
2231 if (VP->getNumElements() != VA->getNumElements())
2233 ElementType = VA->getElementType();
2238 ElementType = VA->getElementType();
2244 S, TemplateParams, VP->getElementType(), ElementType, Info,
Deduced,
2246 false, HasDeducedAnyParam);
2249 case Type::DependentVector: {
2255 S, TemplateParams, VP->getElementType(), VA->getElementType(),
2257 false, HasDeducedAnyParam);
2268 ArgSize = VA->getNumElements();
2275 HasDeducedAnyParam);
2281 S, TemplateParams, VP->getElementType(), VA->getElementType(),
2283 false, HasDeducedAnyParam);
2294 S, TemplateParams, NTTP, VA->getSizeExpr(), Info,
2304 case Type::DependentSizedExtVector: {
2310 S, TemplateParams, VP->getElementType(), VA->getElementType(),
2312 false, HasDeducedAnyParam);
2323 ArgSize = VA->getNumElements();
2328 S, TemplateParams, NTTP, ArgSize, S.
Context.
IntTy,
true, Info,
2335 S, TemplateParams, VP->getElementType(), VA->getElementType(),
2337 false, HasDeducedAnyParam);
2348 S, TemplateParams, NTTP, VA->getSizeExpr(), Info,
2359 case Type::ConstantMatrix: {
2366 if (MP->getNumRows() != MA->getNumRows() ||
2367 MP->getNumColumns() != MA->getNumColumns()) {
2372 S, TemplateParams, MP->getElementType(), MA->getElementType(), Info,
2374 false, HasDeducedAnyParam);
2377 case Type::DependentSizedMatrix: {
2387 false, HasDeducedAnyParam);
2392 auto DeduceMatrixArg =
2393 [&S, &Info, &
Deduced, &TemplateParams, &HasDeducedAnyParam, POK](
2397 const auto *ACM = dyn_cast<ConstantMatrixType>(A);
2398 const auto *ADM = dyn_cast<DependentSizedMatrixType>(A);
2399 if (!ParamExpr->isValueDependent()) {
2400 std::optional<llvm::APSInt> ParamConst =
2401 ParamExpr->getIntegerConstantExpr(S.
Context);
2406 if ((ACM->*GetArgDimension)() == *ParamConst)
2411 Expr *ArgExpr = (ADM->*GetArgDimensionExpr)();
2412 if (std::optional<llvm::APSInt> ArgConst =
2414 if (*ArgConst == *ParamConst)
2425 llvm::APSInt ArgConst(
2427 ArgConst = (ACM->*GetArgDimension)();
2435 S, TemplateParams, NTTP, (ADM->*GetArgDimensionExpr)(), Info,
2439 if (
auto Result = DeduceMatrixArg(MP->getRowExpr(), MA,
2445 return DeduceMatrixArg(MP->getColumnExpr(), MA,
2453 case Type::DependentAddressSpace: {
2459 S, TemplateParams, ASP->getPointeeType(), ASA->getPointeeType(),
2461 false, HasDeducedAnyParam);
2472 S, TemplateParams, NTTP, ASA->getAddrSpaceExpr(), Info,
2483 S, TemplateParams, ASP->getPointeeType(),
2486 false, HasDeducedAnyParam);
2497 S, TemplateParams, NTTP, ArgAddressSpace, S.
Context.
IntTy,
true,
2499 HasDeducedAnyParam);
2504 case Type::DependentBitInt: {
2508 if (IP->isUnsigned() != IA->isUnsigned())
2519 ArgSize = IA->getNumBits();
2522 S, TemplateParams, NTTP, ArgSize,
T,
true, Info,
2527 if (IP->isUnsigned() != IA->isUnsigned())
2535 case Type::TypeOfExpr:
2537 case Type::DependentName:
2538 case Type::UnresolvedUsing:
2539 case Type::Decltype:
2540 case Type::UnaryTransform:
2541 case Type::DeducedTemplateSpecialization:
2542 case Type::PackExpansion:
2544 case Type::ArrayParameter:
2545 case Type::HLSLAttributedResource:
2546 case Type::HLSLInlineSpirv:
2547 case Type::OverflowBehavior:
2551 case Type::PackIndexing: {
2552 const PackIndexingType *PIT = P->
getAs<PackIndexingType>();
2553 if (PIT->hasSelectedType()) {
2555 S, TemplateParams, PIT->getSelectedType(), A, Info,
Deduced, TDF,
2557 false, HasDeducedAnyParam);
2563 llvm_unreachable(
"Invalid Type Class!");
2585 bool *HasDeducedAnyParam) {
2594 llvm_unreachable(
"Null template argument in parameter list");
2602 false, HasDeducedAnyParam);
2614 HasDeducedAnyParam);
2620 llvm_unreachable(
"caller should handle pack expansions");
2674 HasDeducedAnyParam);
2695 llvm_unreachable(
"Unknown template argument kind");
2700 llvm_unreachable(
"Argument packs should be expanded by the caller!");
2703 llvm_unreachable(
"Invalid TemplateArgument Kind!");
2716 if (ArgIdx == Args.size())
2723 assert(ArgIdx == Args.size() - 1 &&
"Pack not at the end of argument list?");
2726 return ArgIdx < Args.size();
2732 bool FoundPackExpansion =
false;
2733 for (
const auto &A : Args) {
2734 if (FoundPackExpansion)
2742 if (A.isPackExpansion())
2743 FoundPackExpansion =
true;
2773 for (
unsigned ArgIdx = 0,
ParamIdx = 0; ; ) {
2779 if (!Ps[
ParamIdx].isPackExpansion()) {
2784 return !FoldPackArgument && NumberOfArgumentsMustMatch
2788 if (As[ArgIdx].isPackExpansion()) {
2793 if (!FoldPackArgument)
2800 S, TemplateParams, Ps[
ParamIdx], Pattern, Info,
2808 if (Ps[
ParamIdx].isPackExpansion())
2814 S, TemplateParams, Ps[
ParamIdx], As[ArgIdx], Info,
2835 PackDeductionScope PackScope(S, TemplateParams,
Deduced, Info, Pattern);
2841 PackScope.hasNextElement();
2843 if (!As[ArgIdx].isPackExpansion()) {
2844 if (!FoldPackParameter)
2846 if (FoldPackArgument)
2856 PackScope.nextPackElement();
2861 return PackScope.finish();
2869 bool NumberOfArgumentsMustMatch) {
2870 return ::DeduceTemplateArguments(
2871 *
this, TemplateParams, Ps, As, Info,
Deduced, NumberOfArgumentsMustMatch,
2881 llvm_unreachable(
"Can't get a NULL template argument here");
2929 llvm_unreachable(
"Invalid TemplateArgument Kind!");
2947 unsigned ArgumentPackIndex) {
2959 Template->getSourceRange().getEnd(), ArgumentPackIndex, CTAI,
2973 CanonicalPackedArgsBuilder;
2981 "deduced nested pack");
2987 S.
Diag(Param->getLocation(),
2988 diag::err_template_arg_deduced_incomplete_pack)
2992 if (ConvertArg(InnerArg, SugaredPackedArgsBuilder.size()))
2997 CanonicalPackedArgsBuilder.push_back(
3003 if (SugaredPackedArgsBuilder.empty()) {
3009 if (
auto *NTTP = dyn_cast<NonTypeTemplateParmDecl>(Param)) {
3014 S.
SubstType(NTTP->getType(), Args, NTTP->getLocation(),
3015 NTTP->getDeclName()).isNull())
3017 }
else if (
auto *TTP = dyn_cast<TemplateTemplateParmDecl>(Param)) {
3033 S.
Context, CanonicalPackedArgsBuilder));
3037 return ConvertArg(Arg, 0);
3049 unsigned NumAlreadyConverted,
bool *IsIncomplete) {
3050 for (
unsigned I = 0, N = TemplateParams->
size(); I != N; ++I) {
3057 if (
Deduced[I].isNull() && Param->isTemplateParameterPack()) {
3059 PackDeductionScope(S, TemplateParams,
Deduced, Info, I).finish();
3065 if (I < NumAlreadyConverted) {
3069 if (Param->isParameterPack() && CurrentInstantiationScope &&
3109 *IsIncomplete =
true;
3116 bool HasDefaultArg =
false;
3129 if (Rec->isLambda())
3130 if (
auto *Method = dyn_cast<CXXMethodDecl>(Rec->getDeclContext())) {
3132 ThisTypeQuals = Method->getMethodQualifiers();
3177 if (
auto *DC = dyn_cast<DeclContext>(D))
3200 bool DeducedArgsNeedReplacement =
false;
3201 if (
auto *TD = dyn_cast<ClassTemplatePartialSpecializationDecl>(
Template)) {
3202 TD->getAssociatedConstraints(AssociatedConstraints);
3203 DeducedArgsNeedReplacement = !TD->isClassScopeExplicitSpecialization();
3204 }
else if (
auto *TD =
3205 dyn_cast<VarTemplatePartialSpecializationDecl>(
Template)) {
3206 TD->getAssociatedConstraints(AssociatedConstraints);
3207 DeducedArgsNeedReplacement = !TD->isClassScopeExplicitSpecialization();
3210 AssociatedConstraints);
3213 std::optional<ArrayRef<TemplateArgument>> Innermost;
3216 if (!DeducedArgsNeedReplacement)
3217 Innermost = SugaredDeducedArgs;
3256 Info.
FirstArg = Ps[ArgIdx].getArgument();
3263 {},
false, InstCTAI,
3276 while (!Stack.empty()) {
3277 auto &Xs = Stack.back();
3282 auto &
X = Xs.front();
3284 Stack.emplace_back(
X.getPackAsArray());
3285 Xs = Xs.drop_front();
3288 assert(!
X.isNull());
3295 auto [Ps, P] = take(PsStack);
3296 auto [As, A] = take(AsStack);
3297 if (P.isNull() && A.isNull())
3300 PA = A.isPackExpansion() ? A.getPackExpansionPattern() : A;
3302 if (!P.isPackExpansion() && !A.isPackExpansion()) {
3304 (AsStack.empty() ? As.end() : AsStack.back().begin()) -
3310 if (P.isPackExpansion()) {
3311 Ps = Ps.drop_front();
3314 if (A.isPackExpansion()) {
3315 As = As.drop_front();
3319 Ps = Ps.drop_front(P.isPackExpansion() ? 0 : 1);
3320 As = As.drop_front(A.isPackExpansion() && !P.isPackExpansion() ? 0 : 1);
3322 assert(PsStack.empty());
3323 assert(AsStack.empty());
3348 if (CopyDeducedArgs) {
3354 Info.
reset(SugaredDeducedArgumentList, CanonicalDeducedArgumentList);
3382 for (
unsigned I = 0, N = Ps.size(); I != N; ++I)
3387 Info, CopyDeducedArgs);
3418template <
typename T>
3419static std::enable_if_t<IsPartialSpecialization<T>::value,
3424 if (Partial->isInvalidDecl())
3443 Deduced.resize(Partial->getTemplateParameters()->size());
3445 S, Partial->getTemplateParameters(),
3446 Partial->getTemplateArgs().asArray(), TemplateArgs, Info,
Deduced,
3460 Result = ::FinishTemplateArgumentDeduction(
3461 S, Partial, Partial->getTemplateParameters(),
3462 Partial->getSpecializedTemplate(),
3464 Partial->getTemplateArgsAsWritten()->arguments(), TemplateArgs, Deduced,
3481 return ::DeduceTemplateArguments(*
this, Partial, TemplateArgs, Info);
3487 return ::DeduceTemplateArguments(*
this, Partial, TemplateArgs, Info);
3497 if (
const auto *CTD = dyn_cast<ClassTemplateDecl>(TD)) {
3499 PType =
Context.getCanonicalTagType(CTD->getTemplatedDecl());
3500 }
else if (
const auto *
AliasTemplate = dyn_cast<TypeAliasTemplateDecl>(TD)) {
3501 PType =
AliasTemplate->getTemplatedDecl()->getUnderlyingType();
3503 assert(
false &&
"Expected a class or alias template");
3522 return DeducedResult;
3532 Result = ::FinishTemplateArgumentDeduction(*this, TD, Deduced, Info);
3546 if (
const TemplateSpecializationType *Spec
3547 =
T->getAs<TemplateSpecializationType>())
3548 return Spec->getTemplateName().getAsTemplateDecl() !=
nullptr;
3577 if (ExplicitTemplateArgs.
size() == 0) {
3580 for (
auto *P :
Function->parameters())
3581 ParamTypes.push_back(P->getType());
3606 ExplicitTemplateArgs, {},
3610 if (Index >= TemplateParams->
size())
3623 CanonicalExplicitArgumentList);
3635 unsigned PartiallySubstitutedPackIndex = -1u;
3643 if (!Expansions || Arg.
pack_size() < *Expansions) {
3653 assert(Proto &&
"Function template does not have a prototype?");
3661 SugaredExplicitArgumentList->
asArray(),
3671 nullptr, ExtParamInfos))
3687 ThisContext =
Method->getParent();
3688 ThisTypeQuals =
Method->getMethodQualifiers();
3702 Diag(
Function->getLocation(), diag::err_kern_type_not_void_return)
3713 nullptr, ExtParamInfos))
3738 for (
unsigned I = 0, N = SugaredExplicitArgumentList->
size(); I != N; ++I) {
3740 if (I == PartiallySubstitutedPackIndex)
3813 if (AQuals == DeducedAQuals) {
3831 bool ObjCLifetimeConversion =
false;
3834 ObjCLifetimeConversion) ||
3856 if (Context.hasSameUnqualifiedType(A, DeducedA))
3880 if (PD->isParameterPack()) {
3883 unsigned NumExpansions = NumArgs ? *NumArgs : 1;
3884 if (Idx + NumExpansions >
ParamIdx)
3886 Idx += NumExpansions;
3889 return std::nullopt;
3894 llvm_unreachable(
"parameter index would not be produced from template");
3949 bool ForOverloadSetAddressResolution,
3950 llvm::function_ref<
bool(
bool)> CheckNonDependent) {
3965 bool IsIncomplete =
false;
3970 NumExplicitlySpecified, PartialOverloading ? &IsIncomplete :
nullptr);
3979 Info.
reset(SugaredDeducedArgumentList, CanonicalDeducedArgumentList);
3988 if (CheckNonDependent(
true))
4000 if (!IsLambda && !IsIncomplete) {
4020 if (CheckNonDependent(
false))
4037 CanonicalDeducedArgumentList)
4048 if (IsLambda && !IsIncomplete) {
4071 if (OriginalCallArgs) {
4076 llvm::SmallDenseMap<std::pair<unsigned, QualType>,
QualType> DeducedATypes;
4077 for (
unsigned I = 0, N = OriginalCallArgs->size(); I != N; ++I) {
4081 unsigned ExplicitOffset =
4083 !ForOverloadSetAddressResolution)
4104 if (CacheEntry.
isNull()) {
4113 DeducedA = CacheEntry;
4128 auto [Pos, Inserted] =
4145 if (Candidate.Specialization &&
4176 DeducedArgLists.reserve(TPLs.size());
4182 Params, PatternArgs, CandidateArgs, Info,
Deduced,
4186 bool IsIncomplete =
false;
4189 *
this, PatternCTD, Params,
false,
Deduced, Info, CTAI,
4190 &InstantiationScope, 0, &IsIncomplete);
4192 for (
unsigned I = 0, N =
Deduced.size(); I != N; ++I) {
4211 DeducedArgLists.push_back(
4223 return Params->hasAssociatedConstraints();
4228 PatternArgLocs.reserve(PatternArgs.size());
4230 PatternArgLocs.push_back(
4237 *
this, CandidateCTD, PatternArgLocs, CandidateArgs, DeducedArgs, Info);
4250 if (Constraints.empty())
4261 CanonicalCandidateArgs.reserve(CandidateArgs.size());
4263 CanonicalCandidateArgs.push_back(
4264 Context.getCanonicalTemplateArgument(Arg));
4269 *
this, PatternCTD, Info,
4283 if (S.
getLangOpts().CPlusPlus14 && Fn->getReturnType()->isUndeducedType() &&
4288 if (Method->isImplicitObjectMemberFunction()) {
4291 if (!R.HasFormOfMemberPointer)
4295 Fn->getType(), std::nullopt, Method->getParent());
4298 if (!R.IsAddressOfOperand)
return Fn->getType();
4309 bool ParamWasReference,
4318 if (ParamWasReference)
4320 if (R.IsAddressOfOperand)
4377 if (ArgType.isNull())
continue;
4381 ArgType->isFunctionType())
4400 S, TemplateParams, ParamType, ArgType, Info,
Deduced, TDF,
4444 assert(Arg &&
"expected a non-null arg expression");
4446 ParamRefType !=
nullptr, FailedTSC);
4447 if (ArgType.isNull())
4453 if (ArgType->isIncompleteArrayType()) {
4454 assert(Arg &&
"expected a non-null arg expression");
4463 if (S.
getLangOpts().OpenCL && !ArgType.hasAddressSpace())
4477 if (ArgType->canDecayToPointerType())
4482 ArgType = ArgType.getUnqualifiedType();
4500 if (ArgType->isPointerType() || ArgType->isMemberPointerType() ||
4501 ArgType->isObjCObjectPointerType())
4528 bool DecomposedParam,
unsigned ArgIdx,
unsigned TDF,
4553 ElTy = ArrTy->getElementType();
4570 S, TemplateParams, 0, ElTy, E->getType(),
4572 OriginalCallArgs,
true, ArgIdx, TDF);
4580 if (
auto *DependentArrTy = dyn_cast_or_null<DependentSizedArrayType>(ArrTy)) {
4583 Info, DependentArrTy->getSizeExpr())) {
4592 S, TemplateParams, NTTP, llvm::APSInt(Size),
T,
4612 bool DecomposedParam,
unsigned ArgIdx,
unsigned TDF,
4615 QualType OrigParamType = ParamType;
4620 S, TemplateParams, FirstInnerIndex, ParamType, ArgType,
4621 ArgClassification, Arg, TDF, FailedTSC))
4625 if (
InitListExpr *ILE = dyn_cast_if_present<InitListExpr>(Arg))
4627 Deduced, OriginalCallArgs, ArgIdx, TDF);
4635 OriginalCallArgs.push_back(
4638 S, TemplateParams, ParamType, ArgType, Info,
Deduced, TDF,
4647 bool PartialOverloading,
bool AggregateDeductionCandidate,
4650 bool ForOverloadSetAddressResolution,
4656 unsigned NumParams =
Function->getNumParams();
4657 bool HasExplicitObject =
false;
4658 int ExplicitObjectOffset = 0;
4666 if (!ForOverloadSetAddressResolution &&
4667 Function->hasCXXExplicitFunctionObjectParameter()) {
4668 HasExplicitObject =
true;
4669 ExplicitObjectOffset = 1;
4678 if (Args.size() <
Function->getMinRequiredExplicitArguments() &&
4679 !PartialOverloading)
4682 PartialOverloading)) {
4684 if (Proto->isTemplateVariadic())
4686 else if (!Proto->isVariadic())
4701 unsigned NumExplicitlySpecified = 0;
4702 if (ExplicitTemplateArgs) {
4705 Result = SubstituteExplicitTemplateArguments(
4706 FunctionTemplate, *ExplicitTemplateArgs, Deduced, ParamTypes, nullptr,
4714 NumExplicitlySpecified =
Deduced.size();
4717 for (
unsigned I = 0; I != NumParams; ++I)
4718 ParamTypes.push_back(
Function->getParamDecl(I)->getType());
4724 auto DeduceCallArgument = [&](
QualType ParamType,
unsigned ArgIdx,
4725 bool ExplicitObjectArgument) {
4733 if (ExplicitObjectArgument) {
4736 *
this, TemplateParams, FirstInnerIndex, ParamType, ObjectType,
4737 ObjectClassification,
4738 nullptr, Info,
Deduced, OriginalCallArgs,
4744 *
this, TemplateParams, FirstInnerIndex, ParamType,
4746 Args[ArgIdx], Info,
Deduced, OriginalCallArgs,
false,
4753 for (
unsigned ParamIdx = 0, NumParamTypes = ParamTypes.size(), ArgIdx = 0;
4757 const PackExpansionType *ParamExpansion =
4758 dyn_cast<PackExpansionType>(ParamType);
4759 if (!ParamExpansion) {
4761 if (ArgIdx >= Args.size() && !(HasExplicitObject &&
ParamIdx == 0))
4764 ParamTypesForArgChecking.push_back(ParamType);
4766 if (
ParamIdx == 0 && HasExplicitObject) {
4770 if (
auto Result = DeduceCallArgument(ParamType, 0,
4777 if (
auto Result = DeduceCallArgument(ParamType, ArgIdx++,
4785 bool IsTrailingPack =
ParamIdx + 1 == NumParamTypes;
4787 QualType ParamPattern = ParamExpansion->getPattern();
4788 PackDeductionScope PackScope(*
this, TemplateParams,
Deduced, Info,
4790 AggregateDeductionCandidate && IsTrailingPack);
4808 if (IsTrailingPack || PackScope.hasFixedArity()) {
4809 for (; ArgIdx < Args.size() && PackScope.hasNextElement();
4810 PackScope.nextPackElement(), ++ArgIdx) {
4811 ParamTypesForArgChecking.push_back(ParamPattern);
4812 if (
auto Result = DeduceCallArgument(ParamPattern, ArgIdx,
4821 UnsignedOrNone NumExpansions = ParamExpansion->getNumExpansions();
4822 if (NumExpansions && !PackScope.isPartiallyExpanded()) {
4823 for (
unsigned I = 0; I != *NumExpansions && ArgIdx < Args.size();
4825 ParamTypesForArgChecking.push_back(ParamPattern);
4828 PackScope.nextPackElement();
4830 }
else if (!IsTrailingPack && !PackScope.isPartiallyExpanded() &&
4831 PackScope.isDeducedFromEarlierParameter()) {
4845 PackScope.getSavedPackSizeIfAllEqual();
4846 if (!ArgPosAfterSubstitution)
4849 unsigned PackArgEnd = ArgIdx + *ArgPosAfterSubstitution;
4850 for (; ArgIdx < PackArgEnd && ArgIdx < Args.size(); ArgIdx++) {
4851 ParamTypesForArgChecking.push_back(ParamPattern);
4853 DeduceCallArgument(ParamPattern, ArgIdx,
4858 PackScope.nextPackElement();
4865 if (
auto Result = PackScope.finish();
4876 Result = FinishTemplateArgumentDeduction(
4877 FunctionTemplate, Deduced, NumExplicitlySpecified, Specialization, Info,
4878 &OriginalCallArgs, PartialOverloading, PartialOrdering,
4879 ForOverloadSetAddressResolution,
4880 [&, CallingCtx](bool OnlyInitializeNonUserDefinedConversions) {
4881 ContextRAII SavedContext(*this, CallingCtx);
4882 return CheckNonDependent(ParamTypesForArgChecking,
4883 OnlyInitializeNonUserDefinedConversions);
4886 if (Trap.hasErrorOccurred()) {
4896 bool AdjustExceptionSpec) {
4897 if (ArgFunctionType.
isNull())
4898 return ArgFunctionType;
4903 bool Rebuild =
false;
4906 if (EPI.ExtInfo.getCC() != CC) {
4907 EPI.ExtInfo = EPI.ExtInfo.withCallingConv(CC);
4911 bool NoReturn = FunctionTypeP->getNoReturnAttr();
4912 if (EPI.ExtInfo.getNoReturn() != NoReturn) {
4913 EPI.ExtInfo = EPI.ExtInfo.withNoReturn(NoReturn);
4917 if (AdjustExceptionSpec && (FunctionTypeP->hasExceptionSpec() ||
4919 EPI.ExceptionSpec = FunctionTypeP->getExtProtoInfo().ExceptionSpec;
4924 return ArgFunctionType;
4934 bool IsAddressOfFunction) {
4954 unsigned NumExplicitlySpecified = 0;
4956 if (ExplicitTemplateArgs) {
4959 Result = SubstituteExplicitTemplateArguments(
4960 FunctionTemplate, *ExplicitTemplateArgs, Deduced, ParamTypes,
4961 &FunctionType, Info);
4968 NumExplicitlySpecified =
Deduced.size();
4974 if (!IsAddressOfFunction)
4982 bool HasDeducedReturnType =
false;
4984 Function->getReturnType()->getContainedAutoType()) {
4986 HasDeducedReturnType =
true;
5007 Result = FinishTemplateArgumentDeduction(
5008 FunctionTemplate, Deduced, NumExplicitlySpecified, Specialization, Info,
5010 true, IsAddressOfFunction);
5053 if (HasDeducedReturnType && IsAddressOfFunction &&
5073 if (!IsAddressOfFunction) {
5079 if (HasDeducedReturnType) {
5088 if (!ArgFunctionType.
isNull()) {
5090 SpecializationType, ArgFunctionType)
5091 : !
Context.hasSameFunctionTypeIgnoringExceptionSpec(
5092 SpecializationType, ArgFunctionType)) {
5130 if (!IsReferenceP) {
5139 assert(!A->
isReferenceType() &&
"Reference types were handled above");
5145 P =
Context.getArrayDecayedType(P);
5150 P =
Context.getPointerType(P);
5205 ParamType, ObjectType, ObjectClassification,
5206 nullptr, Info,
Deduced, OriginalCallArgs,
5213 *
this, TemplateParams, P, A, Info,
Deduced, TDF,
5225 Result = FinishTemplateArgumentDeduction(
5226 ConversionTemplate, Deduced, 0, ConversionSpecialized, Info,
5227 &OriginalCallArgs, false,
5230 Specialization = cast_or_null<CXXConversionDecl>(ConversionSpecialized);
5239 bool IsAddressOfFunction) {
5242 IsAddressOfFunction);
5246 struct DependentAuto {
bool IsPack; };
5250 class SubstituteDeducedTypeTransform :
5258 SubstituteDeducedTypeTransform(
Sema &SemaRef, DependentAuto DA)
5262 UseTypeSugar(
true) {}
5264 SubstituteDeducedTypeTransform(Sema &SemaRef, QualType Replacement,
5265 bool UseTypeSugar =
true)
5266 : TreeTransform<SubstituteDeducedTypeTransform>(SemaRef),
5269 Replacement(Replacement), UseTypeSugar(UseTypeSugar) {
5270 assert((!Replacement.isNull() || UseTypeSugar) &&
5271 "An undeduced auto type is never type sugar");
5274 QualType TransformDesugared(TypeLocBuilder &TLB, DeducedTypeLoc TL) {
5276 "unexpected unsugared replacement kind");
5277 QualType
Result = Replacement;
5278 TemplateTypeParmTypeLoc NewTL = TLB.
push<TemplateTypeParmTypeLoc>(
Result);
5283 QualType TransformAutoType(TypeLocBuilder &TLB, AutoTypeLoc TL) {
5294 return TransformDesugared(TLB, TL);
5297 DK, Replacement, TL.
getTypePtr()->getKeyword(),
5299 TL.
getTypePtr()->getTypeConstraintArguments());
5305 QualType TransformDeducedTemplateSpecializationType(
5306 TypeLocBuilder &TLB, DeducedTemplateSpecializationTypeLoc TL) {
5308 return TransformDesugared(TLB, TL);
5311 DK, Replacement, TL.
getTypePtr()->getKeyword(),
5313 auto NewTL = TLB.
push<DeducedTemplateSpecializationTypeLoc>(
Result);
5320 QualType TransformAtomicType(TypeLocBuilder &TLB, AtomicTypeLoc TL) {
5333 if (isa_and_nonnull<TemplateTypeParmType>(Replacement) &&
5335 return getDerived().TransformType(TLB, TL.
getValueLoc());
5336 return inherited::TransformAtomicType(TLB, TL);
5343 bool TransformExceptionSpec(SourceLocation Loc,
5344 FunctionProtoType::ExceptionSpecInfo &ESI,
5345 SmallVectorImpl<QualType> &Exceptions,
5351 return inherited::TransformExceptionSpec(Loc, ESI, Exceptions, Changed);
5354 QualType Apply(TypeLoc TL) {
5359 return TransformType(TLB, TL);
5377 for (
unsigned I = 0,
C =
TypeLoc.getNumArgs(); I !=
C; ++I)
5393 llvm::raw_string_ostream OS(Buf);
5394 OS <<
"'" <<
Concept->getName();
5395 if (
TypeLoc.hasExplicitTemplateArgs()) {
5396 printTemplateArgumentList(OS,
Type.getTypeConstraintArguments(),
5398 Type.getTypeConstraintConcept()
5399 .getAsTemplateDecl()
5400 ->getTemplateParameters());
5404 diag::err_placeholder_constraints_not_satisfied)
5415 bool IgnoreConstraints,
5418 if (
Init->containsErrors())
5424 if (
Init->getType()->isNonOverloadPlaceholderType() || AT->isDecltypeAuto()) {
5431 DependentAuto DependentResult = {
5434 if (!DependentDeduction &&
5436 Init->containsUnexpandedParameterPack())) {
5437 Result = SubstituteDeducedTypeTransform(*
this, DependentResult).Apply(
Type);
5438 assert(!
Result.isNull() &&
"substituting DependentTy can't fail");
5442 auto *InitList = dyn_cast<InitListExpr>(
Init);
5445 Diag(
Init->getBeginLoc(), diag::err_auto_init_list_from_c)
5446 << (int)AT->getKeyword() << IsArrayType;
5452 Diag(
Type.getBeginLoc(), diag::ext_c23_auto_non_plain_identifier);
5463 if (AT->isDecltypeAuto()) {
5465 Diag(
Init->getBeginLoc(), diag::err_decltype_auto_initializer_list);
5470 assert(!DeducedType.
isNull());
5478 nullptr,
false,
false,
false);
5482 Context, Loc, Loc, TemplParamPtr, Loc,
nullptr);
5488 if (!
Type.getType().getNonReferenceType()->
getAs<AutoType>())
5492 for (
Expr *
Init : InitList->inits()) {
5498 *
this, TemplateParamsSt.get(), 0, TemplArg,
Init->getType(),
5507 <<
Init->getSourceRange();
5515 DeducedFromInitRange =
Init->getSourceRange();
5519 Diag(Loc, diag::err_auto_bitfield);
5523 SubstituteDeducedTypeTransform(*
this, TemplArg).Apply(
Type);
5524 assert(!FuncParam.
isNull() &&
5525 "substituting template parameter for 'auto' failed");
5527 *
this, TemplateParamsSt.get(), 0, FuncParam,
Init->getType(),
5530 false, 0, 0, FailedTSC);
5538 DeducedType =
Deduced[0].getAsType();
5542 if (DeducedType.
isNull())
5553 DeducedType =
Context.getCommonSugaredType(
Result, DeducedType);
5556 if (AT->isConstrained() && !IgnoreConstraints &&
5558 *
this, *AT,
Type.getContainedAutoTypeLoc(), DeducedType))
5561 Result = SubstituteDeducedTypeTransform(*
this, DeducedType).Apply(
Type);
5569 assert((
bool)InitList == OriginalArg.DecomposedParam &&
5570 "decomposed non-init-list in auto deduction?");
5584 assert(TypeToReplaceAuto !=
Context.DependentTy);
5585 return SubstituteDeducedTypeTransform(*
this, TypeToReplaceAuto)
5586 .TransformType(TypeWithAuto);
5591 assert(TypeToReplaceAuto !=
Context.DependentTy);
5592 return SubstituteDeducedTypeTransform(*
this, TypeToReplaceAuto)
5593 .TransformType(TypeWithAuto);
5597 return SubstituteDeducedTypeTransform(
5600 .TransformType(TypeWithAuto);
5605 return SubstituteDeducedTypeTransform(
5608 .TransformType(TypeWithAuto);
5613 return SubstituteDeducedTypeTransform(*
this, TypeToReplaceAuto,
5615 .TransformType(TypeWithAuto);
5620 return SubstituteDeducedTypeTransform(*
this, TypeToReplaceAuto,
5622 .TransformType(TypeWithAuto);
5630 ? diag::err_init_capture_deduction_failure_from_init_list
5631 : diag::err_auto_var_deduction_failure_from_init_list)
5635 VDecl->
isInitCapture() ? diag::err_init_capture_deduction_failure
5636 : diag::err_auto_var_deduction_failure)
5638 <<
Init->getSourceRange();
5670 "failed to deduce lambda return type");
5680 RetType =
Context.getPointerType(RetType);
5683 RetType =
Context.getBlockPointerType(RetType);
5685 Context.adjustDeducedFunctionResultType(FD, RetType);
5697 Diag(Loc, diag::err_auto_fn_used_before_defined) << FD;
5701 return StillUndeduced;
5744 assert(Method && !Method->isExplicitObjectMemberFunction() &&
5745 "expected a member function with no explicit object parameter");
5747 RawType = Context.getQualifiedType(RawType, Method->getMethodQualifiers());
5748 if (Method->getRefQualifier() ==
RQ_RValue ||
5749 (IsOtherRvr && Method->getRefQualifier() ==
RQ_None))
5750 return Context.getRValueReferenceType(RawType);
5751 return Context.getLValueReferenceType(RawType);
5762 bool IsIncompleteSubstitution =
false;
5771 if (IsDeductionGuide) {
5773 P = Injected->getDecl()->getCanonicalTemplateSpecializationType(
5778 if (InstP.
isNull() && !IsIncompleteSubstitution)
5780 if (!CheckConsistency)
5782 if (IsIncompleteSubstitution)
5787 if (
auto *PA = dyn_cast<PackExpansionType>(A);
5789 A = PA->getPattern();
5792 if (IsDeductionGuide) {
5793 if (
auto *Injected = T1->getAsCanonical<InjectedClassNameType>())
5794 T1 = Injected->getDecl()->getCanonicalTemplateSpecializationType(
5796 if (
auto *Injected = T2->getAsCanonical<InjectedClassNameType>())
5797 T2 = Injected->getDecl()->getCanonicalTemplateSpecializationType(
5815 bool IsIncomplete =
false;
5831 Info.
reset(SugaredDeducedArgumentList, CanonicalDeducedArgumentList);
5850 assert(Proto1 && Proto2 &&
"Function templates must have prototypes");
5866 Proto1->
isVariadic() == Proto2->isVariadic() &&
5867 "shouldn't partial order functions with different qualifiers in a "
5868 "context where the function type is used");
5870 assert(Args1.empty() && Args2.empty() &&
5871 "Only call context should have arguments");
5873 Args2 = Proto2->getParamTypes();
5880 bool HasDeducedAnyParamFromReturnType =
false;
5883 S, TemplateParams, Proto2->getReturnType(), Proto1->
getReturnType(),
5886 &HasDeducedAnyParamFromReturnType) !=
5891 llvm::SmallBitVector HasDeducedParam;
5893 HasDeducedParam.resize(Args2.size());
5897 &HasDeducedParam) !=
5912 bool AtLeastAsSpecialized;
5914 AtLeastAsSpecialized =
5915 ::FinishTemplateArgumentDeduction(
5916 S, FT2, Deduced, Info,
5917 [&](Sema &S, FunctionTemplateDecl *FTD,
5918 ArrayRef<TemplateArgument> DeducedArgs) {
5923 if (TPOC != TPOC_Call) {
5924 if (auto TDR = ::CheckDeductionConsistency(
5925 S, FTD, std::nullopt,
5926 Proto2->getReturnType(), Proto1->getReturnType(),
5928 HasDeducedAnyParamFromReturnType);
5929 TDR != TemplateDeductionResult::Success)
5933 if (TPOC == TPOC_Conversion)
5934 return TemplateDeductionResult::Success;
5936 return ::DeduceForEachType(
5937 S, TemplateParams, Args2, Args1, Info, Deduced,
5938 PartialOrderingKind::Call, true,
5939 [&](Sema &S, TemplateParameterList *, int ParamIdx,
5940 UnsignedOrNone ArgIdx, QualType P, QualType A,
5941 TemplateDeductionInfo &Info,
5942 SmallVectorImpl<DeducedTemplateArgument> &Deduced,
5943 PartialOrderingKind) {
5944 if (ArgIdx && *ArgIdx >= static_cast<unsigned>(Args1Offset))
5945 ArgIdx = *ArgIdx - Args1Offset;
5947 ArgIdx = std::nullopt;
5948 return ::CheckDeductionConsistency(
5949 S, FTD, ArgIdx, P, A, DeducedArgs,
5950 HasDeducedParam[ParamIdx]);
5954 if (!AtLeastAsSpecialized || Trap.hasErrorOccurred())
5963 unsigned ArgIdx = 0, NumArgs =
Deduced.size();
5964 for (; ArgIdx != NumArgs; ++ArgIdx)
5968 if (ArgIdx == NumArgs) {
5975 llvm::SmallBitVector UsedParameters(TemplateParams->size());
5978 for (
unsigned I = 0, N = Args2.size(); I != N; ++I)
5980 TemplateParams->getDepth(), UsedParameters);
5986 TemplateParams->getDepth(), UsedParameters);
6011 S.Context.getFunctionTypeWithExceptionSpec(FD2->getType(),
EST_None),
6012 false, TemplateParams->getDepth(), UsedParameters);
6016 for (; ArgIdx != NumArgs; ++ArgIdx)
6019 if (
Deduced[ArgIdx].isNull() && UsedParameters[ArgIdx])
6031 const TemplateSpecializationType *TST1,
6032 const TemplateSpecializationType *TST2) {
6034 As2 = TST2->template_arguments();
6040 assert(As1.size() == As2.size());
6042 unsigned PackSize1 = TA1.
pack_size(), PackSize2 = TA2.pack_size();
6043 bool IsPackExpansion1 =
6045 bool IsPackExpansion2 =
6046 PackSize2 && TA2.pack_elements().back().isPackExpansion();
6047 if (PackSize1 == PackSize2 && IsPackExpansion1 == IsPackExpansion2)
6049 if (PackSize1 > PackSize2 && IsPackExpansion1)
6051 if (PackSize1 < PackSize2 && IsPackExpansion2)
6060 bool PartialOverloading) {
6065 bool ShouldConvert1 =
false;
6066 bool ShouldConvert2 =
false;
6067 bool Args1Offset =
false;
6068 bool Args2Offset =
false;
6079 const CXXMethodDecl *Method1 = dyn_cast<CXXMethodDecl>(FD1);
6080 const CXXMethodDecl *Method2 = dyn_cast<CXXMethodDecl>(FD2);
6091 bool NonStaticMethod1 = Method1 && !Method1->isStatic(),
6092 NonStaticMethod2 = Method2 && !Method2->
isStatic();
6095 Params2Begin = Proto2->param_type_begin();
6097 size_t NumComparedArguments = NumCallArguments1;
6100 (NonStaticMethod1 && NonStaticMethod2) ||
6101 (OO !=
OO_None && OO != OO_Call && OO != OO_Subscript)) {
6103 NonStaticMethod1 && !Method1->hasCXXExplicitFunctionObjectParameter();
6106 NumComparedArguments += 1;
6108 if (ShouldConvert1) {
6112 : Proto2->param_type_begin()[0]->isRValueReferenceType();
6115 RawObj1Ty, IsRValRef2);
6116 Args1.push_back(Obj1Ty);
6119 if (ShouldConvert2) {
6122 ? Method1->getRefQualifier() ==
RQ_RValue
6126 RawObj2Ty, IsRValRef1);
6127 Args2.push_back(Obj2Ty);
6131 if (NonStaticMethod1 && Method1->hasCXXExplicitFunctionObjectParameter())
6136 Args1.insert(Args1.end(), Params1Begin, Proto1->
param_type_end());
6137 Args2.insert(Args2.end(), Params2Begin, Proto2->param_type_end());
6142 Args1.resize(std::min(Args1.size(), NumComparedArguments));
6143 Args2.resize(std::min(Args2.size(), NumComparedArguments));
6146 std::reverse(Args2.begin(), Args2.end());
6148 assert(!
Reversed &&
"Only call context could have reversed arguments");
6151 Args2, Args2Offset);
6153 Args1, Args1Offset);
6157 if (Better1 != Better2)
6158 return Better1 ? FT1 : FT2;
6160 if (!Better1 && !Better2)
6169 Param1.reserve(FD1->
param_size() + ShouldConvert1);
6171 Param1.push_back(Obj1Ty);
6173 Param1.push_back(P->getType());
6176 Param2.reserve(FD2->
param_size() + ShouldConvert2);
6178 Param2.push_back(Obj2Ty);
6180 Param2.push_back(P->getType());
6182 unsigned NumParams1 = Param1.size();
6183 unsigned NumParams2 = Param2.size();
6189 if (Variadic1 != Variadic2) {
6190 if (Variadic1 && NumParams1 > NumParams2)
6192 if (Variadic2 && NumParams2 > NumParams1)
6199 for (
int i = 0, e = std::min(NumParams1, NumParams2);
6200 !PartialOverloading && i < e; ++i) {
6201 QualType T1 = Param1[i].getCanonicalType();
6202 QualType T2 = Param2[i].getCanonicalType();
6203 auto *TST1 = dyn_cast<TemplateSpecializationType>(T1);
6204 auto *TST2 = dyn_cast<TemplateSpecializationType>(T2);
6216 "unknown MoreSpecializedTrailingPackTieBreakerResult value");
6219 if (!
Context.getLangOpts().CPlusPlus20)
6235 if (TPL1->
size() != TPL2->
size() || NumParams1 != NumParams2)
6251 for (
unsigned i = 0; i < NumParams1; ++i)
6252 if (!
Context.hasSameUnqualifiedType(Param1[i], Param2[i]))
6267 bool AtLeastAsConstrained1, AtLeastAsConstrained2;
6272 if (AtLeastAsConstrained1 == AtLeastAsConstrained2)
6274 return AtLeastAsConstrained1 ? FT1 : FT2;
6282 bool Complain,
QualType TargetType) {
6283 if (SpecBegin == SpecEnd) {
6285 Diag(Loc, NoneDiag);
6291 if (SpecBegin + 1 == SpecEnd)
6299 assert(BestTemplate &&
"Not a function template specialization?");
6303 assert(Challenger &&
"Not a function template specialization?");
6308 BestTemplate = Challenger;
6334 Diag(Loc, AmbigDiag);
6341 FD->getPrimaryTemplate()->getTemplateParameters(),
6342 *FD->getTemplateSpecializationArgs());
6343 if (!TargetType.
isNull())
6345 Diag((*I)->getLocation(), PD);
6355 "not for function templates");
6372 bool AtLeastAsConstrained1, AtLeastAsConstrained2;
6377 if (AtLeastAsConstrained1 == AtLeastAsConstrained2)
6379 return AtLeastAsConstrained1 ? FD1 : FD2;
6391template <
typename TemplateLikeDecl>
6393 TemplateLikeDecl *P2,
6423 Deduced.resize(P2->getTemplateParameters()->size());
6444 Result = ::FinishTemplateArgumentDeduction(
6445 S, P2, P2->getTemplateParameters(), Template,
6446 true, Ps, As, Deduced, Info,
6456 template <
typename T1,
typename T2,
6457 std::enable_if_t<std::is_same_v<T1, T2>,
bool> =
true>
6458 T2 *operator()(T1 *, T2 *P2) {
6461 template <
typename T1,
typename T2,
6462 std::enable_if_t<!std::is_same_v<T1, T2>,
bool> =
true>
6463 T1 *operator()(T1 *, T2 *) {
6469struct TemplateArgumentListAreEqual {
6471 TemplateArgumentListAreEqual(ASTContext &Ctx) : Ctx(Ctx) {}
6473 template <
typename T1,
typename T2,
6474 std::enable_if_t<std::is_same_v<T1, T2>,
bool> =
true>
6475 bool operator()(T1 *PS1, T2 *PS2) {
6476 ArrayRef<TemplateArgument> Args1 = PS1->getTemplateArgs().asArray(),
6477 Args2 = PS2->getTemplateArgs().asArray();
6479 for (
unsigned I = 0, E = Args1.size(); I < E; ++I) {
6483 llvm::FoldingSetNodeID IDA, IDB;
6484 Args1[I].Profile(IDA, Ctx);
6485 Args2[I].Profile(IDB, Ctx);
6492 template <
typename T1,
typename T2,
6493 std::enable_if_t<!std::is_same_v<T1, T2>,
bool> =
true>
6494 bool operator()(T1 *Spec, T2 *Primary) {
6495 ArrayRef<TemplateArgument> Args1 = Spec->getTemplateArgs().asArray(),
6496 Args2 = Primary->getInjectedTemplateArgs(Ctx);
6498 for (
unsigned I = 0, E = Args1.size(); I < E; ++I) {
6502 llvm::FoldingSetNodeID IDA, IDB;
6503 Args1[I].Profile(IDA, Ctx);
6537template <
typename TemplateLikeDecl,
typename PrimaryDel>
6538static TemplateLikeDecl *
6541 constexpr bool IsMoreSpecialThanPrimaryCheck =
6542 !std::is_same_v<TemplateLikeDecl, PrimaryDel>;
6545 if constexpr (IsMoreSpecialThanPrimaryCheck)
6548 P2T = P2->getSpecializedTemplate();
6551 if (IsMoreSpecialThanPrimaryCheck && !Better1)
6555 P1->getSpecializedTemplate(), Info);
6556 if (IsMoreSpecialThanPrimaryCheck && !Better2)
6562 if (Better1 != Better2)
6563 return Better1 ? P1 : GetP2()(P1, P2);
6565 if (!Better1 && !Better2)
6574 return GetP2()(P1, P2);
6603 if (!TemplateArgumentListAreEqual(S.
getASTContext())(P1, P2))
6607 P1->getAssociatedConstraints(AC1);
6608 P2->getAssociatedConstraints(AC2);
6609 bool AtLeastAsConstrained1, AtLeastAsConstrained2;
6611 (IsMoreSpecialThanPrimaryCheck && !AtLeastAsConstrained1))
6615 if (AtLeastAsConstrained1 == AtLeastAsConstrained2)
6617 return AtLeastAsConstrained1 ? P1 : GetP2()(P1, P2);
6652 "the partial specializations being compared should specialize"
6653 " the same template.");
6671 Context.canonicalizeTemplateArguments(PrimaryCanonArgs);
6723 for (
unsigned I = 0, N = P->
size(); I != N; ++I) {
6748 if (StrictPackMatch)
6769 *
this, A, AArgs, PArgs, Info,
Deduced,
6775 *StrictPackMatch =
true;
6779 Diag(AArg->
getLocation(), diag::err_template_param_list_different_arity)
6789 diag::err_inconsistent_deduction)
6810 llvm_unreachable(
"Unexpected Result");
6815 TDK = ::FinishTemplateArgumentDeduction(
6816 *this, AArg, AArg->getTemplateParameters(), AArg, PartialOrdering,
6817 AArgs, PArgs, Deduced, Info, false);
6827 assert(PArg->
isInvalidDecl() &&
"Unexpected NonDeducedMismatch");
6851 llvm_unreachable(
"Unexpected Result");
6853 llvm_unreachable(
"Unexpected TDK");
6858 llvm::SmallBitVector &
Used;
6860 bool VisitDeclRefTypes =
true;
6862 MarkUsedTemplateParameterVisitor(llvm::SmallBitVector &
Used,
unsigned Depth,
6863 bool VisitDeclRefTypes =
true)
6864 :
Used(
Used), Depth(Depth), VisitDeclRefTypes(VisitDeclRefTypes) {}
6866 bool VisitTemplateTypeParmType(TemplateTypeParmType *
T)
override {
6867 if (
T->getDepth() == Depth)
6868 Used[
T->getIndex()] =
true;
6873 bool TraverseQualifier)
override {
6874 if (
auto *TTP = llvm::dyn_cast_or_null<TemplateTemplateParmDecl>(
6876 if (TTP->getDepth() == Depth)
6877 Used[TTP->getIndex()] =
true;
6883 bool VisitDeclRefExpr(DeclRefExpr *E)
override {
6884 if (
auto *NTTP = dyn_cast<NonTypeTemplateParmDecl>(E->
getDecl()))
6885 if (NTTP->getDepth() == Depth)
6886 Used[NTTP->getIndex()] =
true;
6887 if (VisitDeclRefTypes)
6892 bool VisitDependentTemplateIdExpr(DependentTemplateIdExpr *E)
override {
6899 bool TraverseSizeOfPackExpr(SizeOfPackExpr *SOPE)
override {
6900 return TraverseDecl(SOPE->
getPack());
6912 llvm::SmallBitVector &
Used) {
6914 MarkUsedTemplateParameterVisitor(
Used, Depth)
6915 .TraverseStmt(
const_cast<Expr *
>(E));
6921 E = Expansion->getPattern();
6925 if (
const auto *DTI = dyn_cast<DependentTemplateIdExpr>(E)) {
6926 Used[DTI->getParameter()->getIndex()] =
true;
6927 for (
const auto &TLoc : DTI->template_arguments())
6949 bool OnlyDeduced,
unsigned Depth,
6950 llvm::SmallBitVector &
Used) {
6964 llvm::SmallBitVector &
Used) {
6967 = dyn_cast<TemplateTemplateParmDecl>(
Template)) {
6988 llvm::SmallBitVector &
Used) {
6993 if (!
T->isDependentType())
6997 switch (
T->getTypeClass()) {
7006 case Type::BlockPointer:
7014 case Type::LValueReference:
7015 case Type::RValueReference:
7023 case Type::MemberPointer: {
7029 OnlyDeduced, Depth,
Used);
7033 case Type::DependentSizedArray:
7036 OnlyDeduced, Depth,
Used);
7040 case Type::ConstantArray:
7041 case Type::IncompleteArray:
7042 case Type::ArrayParameter:
7045 OnlyDeduced, Depth,
Used);
7048 case Type::ExtVector:
7051 OnlyDeduced, Depth,
Used);
7054 case Type::DependentVector: {
7062 case Type::DependentSizedExtVector: {
7072 case Type::DependentAddressSpace: {
7076 OnlyDeduced, Depth,
Used);
7079 OnlyDeduced, Depth,
Used);
7083 case Type::ConstantMatrix: {
7090 case Type::DependentSizedMatrix: {
7101 case Type::FunctionProto: {
7105 for (
unsigned I = 0, N = Proto->
getNumParams(); I != N; ++I) {
7110 if (!OnlyDeduced || I + 1 == N ||
7128 case Type::TemplateTypeParm: {
7130 if (TTP->getDepth() == Depth)
7131 Used[TTP->getIndex()] =
true;
7135 case Type::SubstTemplateTypeParmPack: {
7136 const SubstTemplateTypeParmPackType *Subst
7138 if (Subst->getReplacedParameter()->getDepth() == Depth)
7139 Used[Subst->getIndex()] =
true;
7144 case Type::SubstBuiltinTemplatePack: {
7146 OnlyDeduced, Depth,
Used);
7150 case Type::InjectedClassName:
7153 ->getCanonicalTemplateSpecializationType(Ctx);
7156 case Type::TemplateSpecialization: {
7157 const TemplateSpecializationType *Spec
7174 for (
const auto &Arg : Spec->template_arguments())
7183 OnlyDeduced, Depth,
Used);
7190 OnlyDeduced, Depth,
Used);
7193 case Type::DependentName:
7197 OnlyDeduced, Depth,
Used);
7203 OnlyDeduced, Depth,
Used);
7206 case Type::TypeOfExpr:
7210 OnlyDeduced, Depth,
Used);
7213 case Type::Decltype:
7217 OnlyDeduced, Depth,
Used);
7220 case Type::PackIndexing:
7223 OnlyDeduced, Depth,
Used);
7225 OnlyDeduced, Depth,
Used);
7229 case Type::UnaryTransform:
7232 auto Next = UTT->getUnderlyingType();
7234 Next = UTT->getBaseType();
7239 case Type::PackExpansion:
7242 OnlyDeduced, Depth,
Used);
7246 case Type::DeducedTemplateSpecialization:
7249 OnlyDeduced, Depth,
Used);
7251 case Type::DependentBitInt:
7254 OnlyDeduced, Depth,
Used);
7257 case Type::HLSLAttributedResource:
7264 OnlyDeduced, Depth,
Used);
7269 case Type::VariableArray:
7270 case Type::FunctionNoProto:
7273 case Type::ObjCInterface:
7274 case Type::ObjCObject:
7275 case Type::ObjCObjectPointer:
7276 case Type::UnresolvedUsing:
7279 case Type::HLSLInlineSpirv:
7280 case Type::OverflowBehavior:
7281#define TYPE(Class, Base)
7282#define ABSTRACT_TYPE(Class, Base)
7283#define DEPENDENT_TYPE(Class, Base)
7284#define NON_CANONICAL_TYPE(Class, Base) case Type::Class:
7285#include "clang/AST/TypeNodes.inc"
7297 llvm::SmallBitVector &
Used) {
7315 OnlyDeduced, Depth,
Used);
7333 llvm::SmallBitVector &
Used) {
7338 const Expr *E,
unsigned Depth, llvm::SmallBitVector &
Used) {
7339 MarkUsedTemplateParameterVisitor(
Used, Depth,
false)
7340 .TraverseStmt(
const_cast<Expr *
>(E));
7345 bool OnlyDeduced,
unsigned Depth,
7346 llvm::SmallBitVector &
Used) {
7355 for (
unsigned I = 0, N = TemplateArgs.
size(); I != N; ++I)
7361 bool OnlyDeduced,
unsigned Depth,
7362 llvm::SmallBitVector &
Used) {
7366 for (
unsigned I = 0, N = TemplateArgs.size(); I != N; ++I)
7373 llvm::SmallBitVector &
Used) {
7374 for (
unsigned I = 0, N = TemplateArgs.size(); I != N; ++I)
7376 false, Depth,
Used);
7381 llvm::SmallBitVector &
Deduced) {
7388 for (
unsigned I = 0, N =
Function->getNumParams(); I != N; ++I)
7396 if (!
T->isDependentType())
7401 llvm::SmallBitVector
Deduced(TemplateParams->
size());
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.
Result
Implement __builtin_bit_cast and related operations.
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 AccessResult DeduceTemplateArguments(Sema &S, FriendTemplateDecl *FTD, DeclContext *DC, const TemplateSpecializationType *TST, ArrayRef< TemplateParameterList * > TPLs, TemplateSpecCandidateSet *FailedTSC, MultiLevelTemplateArgumentList &DeducedArgs)
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 void AddFriendTemplateDeductionCandidate(Sema &S, TemplateDecl *TD, TemplateDeductionInfo &Info, TemplateDeductionResult Result, TemplateSpecCandidateSet *FailedTSC)
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...
static TemplateDeductionResult CheckDeducedTemplateArgumentList(Sema &S, TemplateDecl *Template, ArrayRef< TemplateArgumentLoc > Ps, ArrayRef< TemplateArgument > As, const MultiLevelTemplateArgumentList &MLTAL, TemplateDeductionInfo &Info)
PackFold
What directions packs are allowed to match non-packs.
static QualType getTypeOfTemplateArgumentValue(TemplateDeductionInfo &Info, const TemplateArgument &A)
C++26 [temp.deduct.type]p13: When the value of the argument corresponding to a constant template para...
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
QualType getAutoType(DeducedKind DK, QualType DeducedAsType, AutoTypeKeyword Keyword, TemplateName TypeConstraintConcept=TemplateName(), ArrayRef< TemplateArgument > TypeConstraintArgs={}) const
C++11 deduced auto type.
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.
QualType getDeducedTemplateSpecializationType(DeducedKind DK, QualType DeducedAsType, ElaboratedTypeKeyword Keyword, TemplateName Template) const
C++17 deduced class template specialization type.
const DependentSizedArrayType * getAsDependentSizedArrayType(QualType T) const
TypeLoc getValueLoc() 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.
static DeclAccessPair make(NamedDecl *D, AccessSpecifier AS)
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
TemplateTemplateParmDecl * getParameter() const
Represents a vector type where either the type or size is dependent.
virtual bool TraverseTemplateName(TemplateName Template, bool TraverseQualifier=true)
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, bool AllowRelaxedEval=false) const
isIntegerConstantExpr - Return the value if this expression is a valid integer constant expression.
ExtVectorType - Extended vector type.
Stores a list of template parameters and the associated requires-clause (if any) for a TemplateDecl a...
Declaration of a friend template.
Represents a function declaration or definition.
const ParmVarDecl * getParamDecl(unsigned i) const
bool isFunctionTemplateSpecialization() const
Determine whether this function is a function template specialization.
FunctionTemplateDecl * getDescribedFunctionTemplate() const
Retrieves the function template that is described by this function declaration.
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
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() const
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 addOuterTemplateArguments(Decl *AssociatedDecl, ArgList Args, bool Final)
Add a new outmost level to the multi-level template argument list.
void addOuterRetainedLevels(unsigned Num)
bool isAnyArgInstantiationDependent() const
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 hasExplicitTemplateArgs() const
Determines whether this expression had explicit template arguments.
static FindResult find(Expr *E)
Finds the overloaded expression in the given expression E of OverloadTy.
SourceLocation getNameLoc() const
Gets the location of the name.
decls_iterator decls_begin() const
void copyTemplateArgumentsInto(TemplateArgumentListInfo &List) const
Copies the template arguments into the given structure.
decls_iterator decls_end() const
Represents a C++11 pack expansion that produces a sequence of expressions.
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.
QualType getAtomicUnqualifiedType() const
Remove all qualifiers including _Atomic.
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.
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.
TemplateArgumentLoc getTrivialTemplateArgumentLoc(const TemplateArgument &Arg, QualType NTTPType, SourceLocation Loc)
Allocate a TemplateArgumentLoc where all locations have been initialized to the given location.
ExplicitSpecifier instantiateExplicitSpecifier(const MultiLevelTemplateArgumentList &TemplateArgs, ExplicitSpecifier ES)
TemplateDeductionResult SubstituteExplicitTemplateArguments(FunctionTemplateDecl *FunctionTemplate, TemplateArgumentListInfo &ExplicitTemplateArgs, SmallVectorImpl< DeducedTemplateArgument > &Deduced, SmallVectorImpl< QualType > &ParamTypes, QualType *FunctionType, sema::TemplateDeductionInfo &Info)
Substitute the explicitly-provided template arguments into the given function template according to C...
bool SubstParmTypes(SourceLocation Loc, ArrayRef< ParmVarDecl * > Params, const FunctionProtoType::ExtParameterInfo *ExtParamInfos, const MultiLevelTemplateArgumentList &TemplateArgs, SmallVectorImpl< QualType > &ParamTypes, SmallVectorImpl< ParmVarDecl * > *OutParams, ExtParameterInfoBuilder &ParamInfos)
Substitute the given template arguments into the given set of parameters, producing the set of parame...
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)
TemplateParameterList * SubstTemplateParams(TemplateParameterList *Params, DeclContext *Owner, const MultiLevelTemplateArgumentList &TemplateArgs, bool EvaluateConstraints=true)
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.
ExprResult BuildExpressionFromDeclTemplateArgument(const TemplateArgument &Arg, QualType ParamType, SourceLocation Loc)
Given a non-type template argument that refers to a declaration and the type of its corresponding non...
@ Diagnose
Diagnose issues that are non-constant or that are extensions.
TemplateDeductionResult DeduceAutoType(TypeLoc AutoTypeLoc, Expr *Initializer, QualType &Result, sema::TemplateDeductionInfo &Info, bool DependentDeduction=false, bool IgnoreConstraints=false, TemplateSpecCandidateSet *FailedTSC=nullptr)
Deduce the type for an auto type-specifier (C++11 [dcl.spec.auto]p6)
QualType adjustCCAndNoReturn(QualType ArgFunctionType, QualType FunctionType, bool AdjustExceptionSpec=false)
Adjust the type ArgFunctionType to match the calling convention, noreturn, and optionally the excepti...
void HandleFunctionTypeMismatch(PartialDiagnostic &PDiag, QualType FromType, QualType ToType)
HandleFunctionTypeMismatch - Gives diagnostic information for differeing function types.
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...
NamedDecl * getTemplatedDecl() const
Get the underlying, templated declaration.
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
void getAssociatedConstraints(llvm::SmallVectorImpl< AssociatedConstraint > &AC) const
All associated constraints derived from this template parameter list, including the requires clause a...
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...
TemplateSpecCandidate & addCandidate()
Add a new candidate with NumConversions conversion sequence slots to the overload set.
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, int D, int 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.
QualType getType() const
Get the type for which this source info wrapper provides information.
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
Top level wrappers for InstallAPI frontend operations.
@ 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.
OptionalUnsigned< unsigned > UnsignedOrNone
const FunctionProtoType * T
@ Template
We are parsing a template declaration.
ActionResult< CXXBaseSpecifier * > BaseResult
DeductionFailureInfo MakeDeductionFailureInfo(ASTContext &Context, TemplateDeductionResult TDK, sema::TemplateDeductionInfo &Info)
Convert from Sema's representation of template deduction information to the form used in overload-can...
@ FunctionTemplate
The name was classified as a function template name.
@ Concept
The name was classified as a concept name.
bool isLambdaConversionOperator(CXXConversionDecl *C)
@ Deduced
The normal deduced case.
@ Undeduced
Not deduced yet. This is for example an 'auto' which was just parsed.
@ DeducedAsPack
Same as above, but additionally this represents a case where the deduced entity itself is a pack.
@ DeducedAsDependent
This is a special case where the initializer is dependent, so we can't deduce a type yet.
@ 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.
@ PackIndex
Index of a pack indexing expression or 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.
TemplateSpecCandidate - This is a generalization of OverloadCandidate which keeps track of template a...
void set(DeclAccessPair Found, Decl *Spec, DeductionFailureInfo Info)