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");
178 (isa<TemplateTemplateParmDecl>(
Template) &&
179 (cast<TemplateTemplateParmDecl>(
Template)->templateParameterKind() ==
181 cast<TemplateTemplateParmDecl>(
Template)->templateParameterKind() ==
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();
206 return cast<TemplateTemplateParmDecl>(Template);
210 return cast<NonTypeTemplateParmDecl>(Template);
214 if (
const auto *NTTP = dyn_cast<NonTypeTemplateParmDecl>(Template))
220 if (
const auto *NTTP = dyn_cast<NonTypeTemplateParmDecl>(Template))
221 return NTTP->isExpandedParameterPack();
226 if (
const auto *NTTP = dyn_cast<NonTypeTemplateParmDecl>(Template))
227 return NTTP->getLocation();
231 operator bool()
const {
return Template; }
245 if (
const auto *DRE = dyn_cast<DeclRefExpr>(
E))
246 if (
const auto *NTTP = dyn_cast<NonTypeTemplateParmDecl>(DRE->getDecl()))
247 if (NTTP->getDepth() == Depth)
250 if (
const auto *ULE = dyn_cast<UnresolvedLookupExpr>(
E);
251 ULE && (ULE->isConceptReference() || ULE->isVarDeclReference())) {
252 if (
auto *TTP = ULE->getTemplateTemplateDecl()) {
254 if (TTP->getDepth() == Depth)
270 X = NX->getUnderlyingDecl();
271 if (
NamedDecl *NY = dyn_cast<NamedDecl>(Y))
272 Y = NY->getUnderlyingDecl();
285 bool AggregateCandidateDeduction =
false) {
298 QualType XType =
X.getNonTypeTemplateArgumentType();
306 switch (
X.getKind()) {
308 llvm_unreachable(
"Non-deduced template arguments handled above");
315 X.wasDeducedFromArrayBound() ||
321 return X.wasDeducedFromArrayBound() ? Y :
X;
335 return X.wasDeducedFromArrayBound() ? Y :
X;
344 X.structurallyEquals(Y)))
372 llvm::FoldingSetNodeID ID1, ID2;
373 X.getAsExpr()->Profile(ID1, Context,
true);
376 return X.wasDeducedFromArrayBound() ? Y :
X;
383 assert(!
X.wasDeducedFromArrayBound());
396 X.getParamTypeForDecl());
433 (!AggregateCandidateDeduction &&
X.pack_size() != Y.
pack_size()))
445 if (Merged.isNull() && !(XA->isNull() && YA->isNull()))
447 NewPack.push_back(Merged);
450 NewPack.push_back(*XA);
460 llvm_unreachable(
"Invalid TemplateArgument Kind!");
473 bool *HasDeducedAnyParam) {
475 "deducing non-type template argument with wrong depth");
479 if (Result.isNull()) {
483 return TemplateDeductionResult::Inconsistent;
487 return TemplateDeductionResult::Success;
494 return TemplateDeductionResult::Success;
499 if (
auto *Expansion = dyn_cast<PackExpansionType>(ParamType))
500 ParamType = Expansion->getPattern();
514 S, TemplateParams, ParamType, ValueType, Info, Deduced,
528 bool *HasDeducedAnyParam) {
530 S, TemplateParams, NTTP,
532 DeducedFromArrayBound),
544 bool *HasDeducedAnyParam) {
566 bool *HasDeducedAnyParam) {
582 bool *HasDeducedAnyParam) {
594 bool *HasDeducedAnyParam) {
599 return TemplateDeductionResult::Success;
602 if (
auto *TempParam = dyn_cast<TemplateTemplateParmDecl>(ParamDecl)) {
605 return TemplateDeductionResult::Success;
609 unsigned StartPos = 0;
626 Arg, {StartPos, DefaultArguments.drop_front(StartPos)}))
630 S.
Context, Deduced[TempParam->getIndex()], NewDeduced);
631 if (Result.isNull()) {
632 Info.
Param = TempParam;
633 Info.
FirstArg = Deduced[TempParam->getIndex()];
635 return TemplateDeductionResult::Inconsistent;
638 Deduced[TempParam->getIndex()] = Result;
639 if (HasDeducedAnyParam)
640 *HasDeducedAnyParam =
true;
641 return TemplateDeductionResult::Success;
647 return TemplateDeductionResult::Success;
652 return TemplateDeductionResult::NonDeducedMismatch;
693 bool *HasDeducedAnyParam) {
696 if (isa<TemplateSpecializationType>(
P.getCanonicalType())) {
705 TNP = TT->getTemplateName(S.
Context);
706 PResolved = TT->getTemplateArgs(S.
Context);
711 return TemplateDeductionResult::Success;
714 return TemplateDeductionResult::Success;
723 return TemplateDeductionResult::Success;
730 ->template_arguments();
737 Result != TemplateDeductionResult::Success)
744 S, TemplateParams, PResolved, AResolved, Info, Deduced,
758 TNA = TST->getTemplateName();
760 TNA = TA->getTemplateName(S.
Context);
765 return TemplateDeductionResult::NonDeducedMismatch;
774 Result != TemplateDeductionResult::Success)
779 S, TemplateParams, PResolved, AResolved, Info, Deduced,
788 case Type::TypeOfExpr:
790 case Type::DependentName:
792 case Type::PackIndexing:
793 case Type::UnresolvedUsing:
794 case Type::TemplateTypeParm:
798 case Type::ConstantArray:
799 case Type::IncompleteArray:
800 case Type::VariableArray:
801 case Type::DependentSizedArray:
803 cast<ArrayType>(
T)->getElementType().getTypePtr());
852class PackDeductionScope {
860 bool DeducePackIfNotAlreadyDeduced =
false,
861 bool FinishingDeduction =
false)
862 : S(S), TemplateParams(TemplateParams), Deduced(Deduced), Info(Info),
863 DeducePackIfNotAlreadyDeduced(DeducePackIfNotAlreadyDeduced),
864 FinishingDeduction(FinishingDeduction) {
865 unsigned NumNamedPacks = addPacks(Pattern);
866 finishConstruction(NumNamedPacks);
873 : S(S), TemplateParams(TemplateParams), Deduced(Deduced), Info(Info) {
875 finishConstruction(1);
879 void addPack(
unsigned Index) {
882 DeducedFromEarlierParameter = !Deduced[Index].isNull();
884 if (!FinishingDeduction) {
885 Pack.Saved = Deduced[Index];
894 FixedNumExpansions = ExpandedPackExpansions;
896 Packs.push_back(Pack);
902 llvm::SmallBitVector SawIndices(TemplateParams->size());
905 auto AddPack = [&](
unsigned Index) {
906 if (SawIndices[Index])
908 SawIndices[Index] =
true;
915 if (
auto *NTTP = dyn_cast<NonTypeTemplateParmDecl>(
916 TemplateParams->getParam(Index))) {
917 if (!NTTP->isExpandedParameterPack())
920 if (
auto *Expansion = dyn_cast<PackExpansionType>(
922 ExtraDeductions.push_back(Expansion->getPattern());
931 for (
unsigned I = 0, N = Unexpanded.size(); I != N; ++I) {
932 unsigned Depth, Index;
934 std::tie(Depth, Index) = *DI;
938 if (Depth == Info.getDeducedDepth())
946 unsigned NumNamedPacks = Packs.size();
950 while (!ExtraDeductions.empty())
951 Collect(ExtraDeductions.pop_back_val());
953 return NumNamedPacks;
956 void finishConstruction(
unsigned NumNamedPacks) {
959 unsigned NumPartialPackArgs = 0;
960 std::pair<unsigned, unsigned> PartialPackDepthIndex(-1u, -1u);
962 if (
auto *Partial =
Scope->getPartiallySubstitutedPack(
963 &PartialPackArgs, &NumPartialPackArgs))
969 bool IsExpanded =
true;
970 for (
unsigned I = 0; I != NumNamedPacks; ++I) {
971 if (Packs[I].Index >= Info.getNumExplicitArgs()) {
973 IsPartiallyExpanded =
false;
976 if (PartialPackDepthIndex ==
977 std::make_pair(Info.getDeducedDepth(), Packs[I].Index)) {
978 IsPartiallyExpanded =
true;
986 if (IsPartiallyExpanded)
987 PackElements += NumPartialPackArgs;
988 else if (IsExpanded && FixedNumExpansions)
989 PackElements += *FixedNumExpansions;
991 for (
auto &Pack : Packs) {
992 if (Info.PendingDeducedPacks.size() > Pack.Index)
993 Pack.Outer = Info.PendingDeducedPacks[Pack.Index];
995 Info.PendingDeducedPacks.resize(Pack.Index + 1);
996 Info.PendingDeducedPacks[Pack.Index] = &Pack;
998 if (PartialPackDepthIndex ==
999 std::make_pair(Info.getDeducedDepth(), Pack.Index)) {
1000 Pack.New.append(PartialPackArgs, PartialPackArgs + NumPartialPackArgs);
1009 if (!FinishingDeduction && !IsPartiallyExpanded)
1010 Deduced[Pack.Index] = Pack.New[PackElements];
1016 ~PackDeductionScope() {
1017 for (
auto &Pack : Packs)
1018 Info.PendingDeducedPacks[Pack.Index] = Pack.Outer;
1023 unsigned PackSize = Packs[0].Saved.pack_size();
1025 if (std::all_of(Packs.begin() + 1, Packs.end(), [&PackSize](
const auto &
P) {
1026 return P.Saved.pack_size() == PackSize;
1029 return std::nullopt;
1034 bool isDeducedFromEarlierParameter()
const {
1035 return DeducedFromEarlierParameter;
1040 bool isPartiallyExpanded() {
return IsPartiallyExpanded; }
1045 bool hasFixedArity() {
return static_cast<bool>(FixedNumExpansions); }
1050 bool hasNextElement() {
1051 return !FixedNumExpansions || *FixedNumExpansions > PackElements;
1055 void nextPackElement() {
1059 if (!FinishingDeduction) {
1060 for (
auto &Pack : Packs) {
1062 if (!Pack.New.empty() || !DeducedArg.
isNull()) {
1063 while (Pack.New.size() < PackElements)
1065 if (Pack.New.size() == PackElements)
1066 Pack.New.push_back(DeducedArg);
1068 Pack.New[PackElements] = DeducedArg;
1069 DeducedArg = Pack.New.size() > PackElements + 1
1070 ? Pack.New[PackElements + 1]
1082 if (FinishingDeduction)
1083 return TemplateDeductionResult::Success;
1086 for (
auto &Pack : Packs) {
1088 if (!FinishingDeduction)
1089 Deduced[Pack.Index] = Pack.Saved;
1104 Pack.New.resize(PackElements);
1108 if (Pack.New.empty()) {
1114 std::copy(Pack.New.begin(), Pack.New.end(), ArgumentPack);
1122 Pack.New[0].wasDeducedFromArrayBound());
1128 if (Pack.Outer->DeferredDeduction.isNull()) {
1131 Pack.Outer->DeferredDeduction = NewPack;
1134 Loc = &Pack.Outer->DeferredDeduction;
1136 Loc = &Deduced[Pack.Index];
1142 S.
Context, OldPack, NewPack, DeducePackIfNotAlreadyDeduced);
1144 Info.AggregateDeductionCandidateHasMismatchedArity =
1150 if (!Result.isNull() && !Pack.DeferredDeduction.isNull()) {
1152 NewPack = Pack.DeferredDeduction;
1156 NamedDecl *Param = TemplateParams->getParam(Pack.Index);
1157 if (Result.isNull()) {
1159 Info.FirstArg = OldPack;
1160 Info.SecondArg = NewPack;
1161 return TemplateDeductionResult::Inconsistent;
1167 if (*Expansions != PackElements) {
1169 Info.FirstArg = Result;
1170 return TemplateDeductionResult::IncompletePack;
1177 return TemplateDeductionResult::Success;
1185 unsigned PackElements = 0;
1186 bool IsPartiallyExpanded =
false;
1187 bool DeducePackIfNotAlreadyDeduced =
false;
1188 bool DeducedFromEarlierParameter =
false;
1189 bool FinishingDeduction =
false;
1203 bool FinishingDeduction,
T &&DeductFunc) {
1213 = dyn_cast<PackExpansionType>(Params[
ParamIdx]);
1218 if (ArgIdx >= Args.size())
1219 return TemplateDeductionResult::MiscellaneousDeductionFailure;
1221 if (isa<PackExpansionType>(Args[ArgIdx])) {
1226 return TemplateDeductionResult::MiscellaneousDeductionFailure;
1230 DeductFunc(S, TemplateParams,
ParamIdx, ArgIdx,
1231 Params[
ParamIdx].getUnqualifiedType(),
1232 Args[ArgIdx].getUnqualifiedType(), Info, Deduced, POK);
1233 Result != TemplateDeductionResult::Success)
1248 PackDeductionScope PackScope(S, TemplateParams, Deduced, Info, Pattern,
1250 FinishingDeduction);
1254 if (
ParamIdx + 1 == Params.size() || PackScope.hasFixedArity()) {
1255 for (; ArgIdx < Args.size() && PackScope.hasNextElement(); ++ArgIdx) {
1258 S, TemplateParams,
ParamIdx, ArgIdx,
1260 Info, Deduced, POK);
1261 Result != TemplateDeductionResult::Success)
1263 PackScope.nextPackElement();
1284 if (NumExpansions && !PackScope.isPartiallyExpanded()) {
1285 for (
unsigned I = 0; I != *NumExpansions && ArgIdx < Args.size();
1287 PackScope.nextPackElement();
1293 if (
auto Result = PackScope.finish();
1294 Result != TemplateDeductionResult::Success)
1305 isa<PackExpansionType>(Args[ArgIdx]))
1306 return TemplateDeductionResult::Success;
1309 if (ArgIdx < Args.size())
1310 return TemplateDeductionResult::MiscellaneousDeductionFailure;
1312 return TemplateDeductionResult::Success;
1352 llvm::SmallBitVector *HasDeducedParam) {
1353 return ::DeduceForEachType(
1354 S, TemplateParams, Params, Args, Info, Deduced, POK,
1360 bool HasDeducedAnyParamCopy =
false;
1362 S, TemplateParams,
P, A, Info, Deduced, TDF, POK,
1363 false, &HasDeducedAnyParamCopy);
1364 if (HasDeducedAnyParam && HasDeducedAnyParamCopy)
1365 *HasDeducedAnyParam =
true;
1366 if (HasDeducedParam && HasDeducedAnyParamCopy)
1367 (*HasDeducedParam)[
ParamIdx] =
true;
1381 if (ParamQs == ArgQs)
1425 if (!Guide || !Guide->isImplicit())
1427 return Guide->getDeducedTemplate()->getTemplateParameters()->size();
1437 if (ParamRef->getPointeeType().getQualifiers())
1441 return TypeParm && TypeParm->
getIndex() >= FirstInnerIndex;
1469 bool *HasDeducedAnyParam) {
1495 bool HasDeducedAnyParam;
1497 llvm::MapVector<const CXXRecordDecl *, MatchValue> Matches;
1502 assert(
T->
isRecordType() &&
"Base class that isn't a record?");
1504 ToVisit.push_back(
T);
1513 while (!ToVisit.empty()) {
1514 QualType NextT = ToVisit.pop_back_val();
1519 bool HasDeducedAnyParamCopy =
false;
1522 &HasDeducedAnyParamCopy);
1528 Matches.insert({RD, {DeducedCopy, HasDeducedAnyParamCopy}});
1539 if (Matches.size() > 1) {
1541 for (
const auto &
Match : Matches)
1542 AddBases(
Match.first);
1546 while (Matches.size() > 1 && !ToVisit.empty()) {
1547 const CXXRecordDecl *RD = ToVisit.pop_back_val()->getAsCXXRecordDecl();
1556 if (Matches.empty())
1558 if (Matches.size() > 1)
1561 std::swap(Matches.front().second.Deduced, Deduced);
1562 if (
bool HasDeducedAnyParamCopy = Matches.front().second.HasDeducedAnyParam;
1563 HasDeducedAnyParamCopy && HasDeducedAnyParam)
1564 *HasDeducedAnyParam = HasDeducedAnyParamCopy;
1573 return std::min(POK, PartialOrderingKind::NonCall);
1605 bool *HasDeducedAnyParam) {
1609 if (
const auto *AExp = dyn_cast<PackExpansionType>(A))
1610 A = AExp->getPattern();
1613 if (POK == PartialOrderingKind::Call) {
1691 TDF &= ~TDF_TopLevelParameterTypeList;
1694 P =
P->getPointeeType();
1711 unsigned Index = TTP->getIndex();
1726 Info.
Param = cast<TemplateTypeParmDecl>(TemplateParams->
getParam(Index));
1738 "saw template type parameter with wrong depth");
1740 "Unresolved overloaded function");
1760 Info.
Param = cast<TemplateTypeParmDecl>(TemplateParams->
getParam(Index));
1783 case Decl::TemplateTypeParm:
1784 Info.
Param = cast<TemplateTypeParmDecl>(Param);
1786 case Decl::NonTypeTemplateParm:
1787 Info.
Param = cast<NonTypeTemplateParmDecl>(Param);
1789 case Decl::TemplateTemplateParm:
1790 Info.
Param = cast<TemplateTemplateParmDecl>(Param);
1793 llvm_unreachable(
"unexpected kind");
1801 if (HasDeducedAnyParam)
1802 *HasDeducedAnyParam =
true;
1842 if (!
P->isDependentType()) {
1858 switch (
P.getCanonicalType()->getTypeClass()) {
1860#define NON_CANONICAL_TYPE(Class, Base) \
1861 case Type::Class: llvm_unreachable("deducing non-canonical type: " #Class);
1862#define TYPE(Class, Base)
1863#include "clang/AST/TypeNodes.inc"
1865 case Type::TemplateTypeParm:
1866 case Type::SubstTemplateTypeParmPack:
1867 case Type::SubstBuiltinTemplatePack:
1868 llvm_unreachable(
"Type nodes handled above");
1876 if (
P->isDependentType())
1880 case Type::VariableArray:
1882 case Type::FunctionNoProto:
1885 case Type::ObjCObject:
1886 case Type::ObjCInterface:
1887 case Type::ObjCObjectPointer:
1897 case Type::Complex: {
1902 S, TemplateParams, CP->getElementType(), CA->getElementType(), Info,
1904 false, HasDeducedAnyParam);
1908 case Type::Atomic: {
1913 S, TemplateParams, PA->getValueType(), AA->getValueType(), Info,
1915 false, HasDeducedAnyParam);
1919 case Type::Pointer: {
1930 PointeeType, Info, Deduced,
1933 false, HasDeducedAnyParam);
1937 case Type::LValueReference: {
1944 S, TemplateParams, RP->getPointeeType(), RA->getPointeeType(), Info,
1946 false, HasDeducedAnyParam);
1950 case Type::RValueReference: {
1957 S, TemplateParams, RP->getPointeeType(), RA->getPointeeType(), Info,
1959 false, HasDeducedAnyParam);
1963 case Type::IncompleteArray: {
1969 assert(IAP &&
"Template parameter not of incomplete array type");
1972 S, TemplateParams, IAP->getElementType(), IAA->getElementType(), Info,
1975 false, HasDeducedAnyParam);
1979 case Type::ConstantArray: {
1983 if (!CAA || CAA->getSize() != CAP->getSize())
1987 S, TemplateParams, CAP->getElementType(), CAA->getElementType(), Info,
1990 false, HasDeducedAnyParam);
1994 case Type::DependentSizedArray: {
2003 S, TemplateParams, DAP->getElementType(), AA->getElementType(),
2006 false, HasDeducedAnyParam);
2019 "saw non-type template parameter with wrong depth");
2020 if (
const auto *CAA = dyn_cast<ConstantArrayType>(AA)) {
2021 llvm::APSInt Size(CAA->getSize());
2024 true, Info, POK != PartialOrderingKind::None,
2025 Deduced, HasDeducedAnyParam);
2027 if (
const auto *DAA = dyn_cast<DependentSizedArrayType>(AA))
2028 if (DAA->getSizeExpr())
2030 S, TemplateParams, NTTP, DAA->getSizeExpr(), Info,
2031 POK != PartialOrderingKind::None, Deduced, HasDeducedAnyParam);
2040 case Type::FunctionProto: {
2046 if (FPP->getMethodQuals() != FPA->getMethodQuals() ||
2047 FPP->getRefQualifier() != FPA->getRefQualifier() ||
2048 FPP->isVariadic() != FPA->isVariadic())
2053 S, TemplateParams, FPP->getReturnType(), FPA->getReturnType(),
2055 false, HasDeducedAnyParam);
2061 S, TemplateParams, FPP->param_types(), FPA->param_types(), Info,
2074 Expr *NoexceptExpr = FPP->getNoexceptExpr();
2079 "saw non-type template parameter with wrong depth");
2082 switch (FPA->canThrow()) {
2093 POK != PartialOrderingKind::None, Deduced, HasDeducedAnyParam);
2096 if (
Expr *ArgNoexceptExpr = FPA->getNoexceptExpr())
2098 S, TemplateParams, NTTP, ArgNoexceptExpr, Info,
2099 POK != PartialOrderingKind::None, Deduced, HasDeducedAnyParam);
2112 case Type::InjectedClassName:
2121 case Type::TemplateSpecialization: {
2126 POK != PartialOrderingKind::None,
2127 Deduced, HasDeducedAnyParam);
2133 S, TemplateParams,
P, A, Info, POK != PartialOrderingKind::None,
2134 Deduced, HasDeducedAnyParam);
2149 Deduced = DeducedOrig;
2153 POK != PartialOrderingKind::None,
2154 Deduced, HasDeducedAnyParam);
2168 case Type::MemberPointer: {
2185 S, TemplateParams, PPT, APT, Info, Deduced, SubTDF,
2187 false, HasDeducedAnyParam);
2194 :
QualType(MPP->getQualifier().getAsType(), 0);
2195 assert(!TP.
isNull() &&
"member pointer with non-type class");
2200 :
QualType(MPA->getQualifier().getAsType(), 0)
2202 assert(!TA.
isNull() &&
"member pointer with non-type class");
2205 S, TemplateParams, TP, TA, Info, Deduced, SubTDF,
2207 false, HasDeducedAnyParam);
2215 case Type::BlockPointer: {
2221 S, TemplateParams, BPP->getPointeeType(), BPA->getPointeeType(), Info,
2223 false, HasDeducedAnyParam);
2229 case Type::ExtVector: {
2234 if (VP->getNumElements() != VA->getNumElements())
2236 ElementType = VA->getElementType();
2241 ElementType = VA->getElementType();
2247 S, TemplateParams, VP->getElementType(), ElementType, Info, Deduced,
2249 false, HasDeducedAnyParam);
2252 case Type::DependentVector: {
2258 S, TemplateParams, VP->getElementType(), VA->getElementType(),
2260 false, HasDeducedAnyParam);
2271 ArgSize = VA->getNumElements();
2277 Info, POK != PartialOrderingKind::None, Deduced,
2278 HasDeducedAnyParam);
2284 S, TemplateParams, VP->getElementType(), VA->getElementType(),
2286 false, HasDeducedAnyParam);
2297 S, TemplateParams, NTTP, VA->getSizeExpr(), Info,
2298 POK != PartialOrderingKind::None, Deduced, HasDeducedAnyParam);
2307 case Type::DependentSizedExtVector: {
2313 S, TemplateParams, VP->getElementType(), VA->getElementType(),
2315 false, HasDeducedAnyParam);
2326 ArgSize = VA->getNumElements();
2331 S, TemplateParams, NTTP, ArgSize, S.
Context.
IntTy,
true, Info,
2332 POK != PartialOrderingKind::None, Deduced, HasDeducedAnyParam);
2338 S, TemplateParams, VP->getElementType(), VA->getElementType(),
2340 false, HasDeducedAnyParam);
2351 S, TemplateParams, NTTP, VA->getSizeExpr(), Info,
2352 POK != PartialOrderingKind::None, Deduced, HasDeducedAnyParam);
2362 case Type::ConstantMatrix: {
2369 if (MP->getNumRows() != MA->getNumRows() ||
2370 MP->getNumColumns() != MA->getNumColumns()) {
2375 S, TemplateParams, MP->getElementType(), MA->getElementType(), Info,
2377 false, HasDeducedAnyParam);
2380 case Type::DependentSizedMatrix: {
2390 false, HasDeducedAnyParam);
2395 auto DeduceMatrixArg =
2396 [&S, &Info, &Deduced, &TemplateParams, &HasDeducedAnyParam, POK](
2400 const auto *ACM = dyn_cast<ConstantMatrixType>(A);
2401 const auto *ADM = dyn_cast<DependentSizedMatrixType>(A);
2402 if (!ParamExpr->isValueDependent()) {
2403 std::optional<llvm::APSInt> ParamConst =
2404 ParamExpr->getIntegerConstantExpr(S.
Context);
2409 if ((ACM->*GetArgDimension)() == *ParamConst)
2414 Expr *ArgExpr = (ADM->*GetArgDimensionExpr)();
2415 if (std::optional<llvm::APSInt> ArgConst =
2417 if (*ArgConst == *ParamConst)
2428 llvm::APSInt ArgConst(
2430 ArgConst = (ACM->*GetArgDimension)();
2433 true, Info, POK != PartialOrderingKind::None,
2434 Deduced, HasDeducedAnyParam);
2438 S, TemplateParams, NTTP, (ADM->*GetArgDimensionExpr)(), Info,
2439 POK != PartialOrderingKind::None, Deduced, HasDeducedAnyParam);
2442 if (
auto Result = DeduceMatrixArg(MP->getRowExpr(), MA,
2448 return DeduceMatrixArg(MP->getColumnExpr(), MA,
2456 case Type::DependentAddressSpace: {
2462 S, TemplateParams, ASP->getPointeeType(), ASA->getPointeeType(),
2464 false, HasDeducedAnyParam);
2475 S, TemplateParams, NTTP, ASA->getAddrSpaceExpr(), Info,
2476 POK != PartialOrderingKind::None, Deduced, HasDeducedAnyParam);
2486 S, TemplateParams, ASP->getPointeeType(),
2489 false, HasDeducedAnyParam);
2500 S, TemplateParams, NTTP, ArgAddressSpace, S.
Context.
IntTy,
true,
2501 Info, POK != PartialOrderingKind::None, Deduced,
2502 HasDeducedAnyParam);
2507 case Type::DependentBitInt: {
2511 if (IP->isUnsigned() != IA->isUnsigned())
2520 ArgSize = IA->getNumBits();
2523 S, TemplateParams, NTTP, ArgSize, S.
Context.
IntTy,
true, Info,
2524 POK != PartialOrderingKind::None, Deduced, HasDeducedAnyParam);
2528 if (IP->isUnsigned() != IA->isUnsigned())
2536 case Type::TypeOfExpr:
2538 case Type::DependentName:
2539 case Type::UnresolvedUsing:
2540 case Type::Decltype:
2541 case Type::UnaryTransform:
2542 case Type::DeducedTemplateSpecialization:
2543 case Type::DependentTemplateSpecialization:
2544 case Type::PackExpansion:
2546 case Type::ArrayParameter:
2547 case Type::HLSLAttributedResource:
2548 case Type::HLSLInlineSpirv:
2552 case Type::PackIndexing: {
2558 false, HasDeducedAnyParam);
2564 llvm_unreachable(
"Invalid Type Class!");
2572 bool *HasDeducedAnyParam) {
2579 switch (
P.getKind()) {
2581 llvm_unreachable(
"Null template argument in parameter list");
2586 S, TemplateParams,
P.getAsType(), A.
getAsType(), Info, Deduced, 0,
2588 : PartialOrderingKind::None,
2589 false, HasDeducedAnyParam);
2601 HasDeducedAnyParam);
2607 llvm_unreachable(
"caller should handle pack expansions");
2628 if (llvm::APSInt::isSameValue(
P.getAsIntegral(), A.
getAsIntegral()))
2658 if (
const auto *ICE = dyn_cast<ImplicitCastExpr>(
E);
2659 ICE && ICE->getCastKind() == clang::CK_Dependent) {
2660 E = ICE->getSubExpr();
2662 S, TemplateParams, ICE->getType(),
E->
getType(), Info,
2665 : PartialOrderingKind::None,
2666 false, HasDeducedAnyParam);
2679 HasDeducedAnyParam);
2684 Deduced, HasDeducedAnyParam);
2700 llvm_unreachable(
"Unknown template argument kind");
2705 llvm_unreachable(
"Argument packs should be expanded by the caller!");
2708 llvm_unreachable(
"Invalid TemplateArgument Kind!");
2721 if (ArgIdx == Args.size())
2728 assert(ArgIdx == Args.size() - 1 &&
"Pack not at the end of argument list?");
2731 return ArgIdx < Args.size();
2737 bool FoundPackExpansion =
false;
2738 for (
const auto &A : Args) {
2739 if (FoundPackExpansion)
2747 if (A.isPackExpansion())
2748 FoundPackExpansion =
true;
2762 bool FoldPackParameter =
PackFold == PackFold::ParameterToArgument ||
2764 FoldPackArgument =
PackFold == PackFold::ArgumentToParameter ||
2778 for (
unsigned ArgIdx = 0,
ParamIdx = 0; ; ) {
2784 if (!Ps[
ParamIdx].isPackExpansion()) {
2789 return !FoldPackArgument && NumberOfArgumentsMustMatch
2793 if (As[ArgIdx].isPackExpansion()) {
2798 if (!FoldPackArgument)
2805 S, TemplateParams, Ps[
ParamIdx], Pattern, Info,
2813 if (Ps[
ParamIdx].isPackExpansion())
2819 S, TemplateParams, Ps[
ParamIdx], As[ArgIdx], Info,
2840 PackDeductionScope PackScope(S, TemplateParams, Deduced, Info, Pattern);
2846 PackScope.hasNextElement();
2848 if (!As[ArgIdx].isPackExpansion()) {
2849 if (!FoldPackParameter)
2851 if (FoldPackArgument)
2857 Deduced, HasDeducedAnyParam);
2861 PackScope.nextPackElement();
2866 return PackScope.finish();
2874 bool NumberOfArgumentsMustMatch) {
2875 return ::DeduceTemplateArguments(
2876 *
this, TemplateParams, Ps, As, Info, Deduced, NumberOfArgumentsMustMatch,
2877 false, PackFold::ParameterToArgument,
2887 llvm_unreachable(
"Can't get a NULL template argument here");
2936 llvm_unreachable(
"Invalid TemplateArgument Kind!");
2954 unsigned ArgumentPackIndex) {
2966 Template->getSourceRange().getEnd(), ArgumentPackIndex, CTAI,
2980 CanonicalPackedArgsBuilder;
2988 "deduced nested pack");
2995 diag::err_template_arg_deduced_incomplete_pack)
2999 if (ConvertArg(InnerArg, SugaredPackedArgsBuilder.size()))
3004 CanonicalPackedArgsBuilder.push_back(
3010 if (SugaredPackedArgsBuilder.empty()) {
3016 if (
auto *NTTP = dyn_cast<NonTypeTemplateParmDecl>(Param)) {
3021 S.
SubstType(NTTP->getType(), Args, NTTP->getLocation(),
3022 NTTP->getDeclName()).isNull())
3024 }
else if (
auto *TTP = dyn_cast<TemplateTemplateParmDecl>(Param)) {
3038 S.
Context, CanonicalPackedArgsBuilder));
3042 return ConvertArg(Arg, 0);
3054 unsigned NumAlreadyConverted,
bool *IsIncomplete) {
3055 for (
unsigned I = 0, N = TemplateParams->
size(); I != N; ++I) {
3064 PackDeductionScope(S, TemplateParams, Deduced, Info, I).finish();
3069 if (!Deduced[I].isNull()) {
3070 if (I < NumAlreadyConverted) {
3114 *IsIncomplete =
true;
3121 bool HasDefaultArg =
false;
3124 assert(isa<ClassTemplatePartialSpecializationDecl>(
Template) ||
3125 isa<VarTemplatePartialSpecializationDecl>(
Template));
3134 if (Rec->isLambda())
3135 if (
auto *
Method = dyn_cast<CXXMethodDecl>(Rec->getDeclContext())) {
3136 ThisContext =
Method->getParent();
3137 ThisTypeQuals =
Method->getMethodQualifiers();
3182 if (
auto *DC = dyn_cast<DeclContext>(
D))
3188 static constexpr bool value =
false;
3192 static constexpr bool value =
true;
3196 static constexpr bool value =
true;
3205 bool DeducedArgsNeedReplacement =
false;
3206 if (
auto *TD = dyn_cast<ClassTemplatePartialSpecializationDecl>(
Template)) {
3207 TD->getAssociatedConstraints(AssociatedConstraints);
3208 DeducedArgsNeedReplacement = !TD->isClassScopeExplicitSpecialization();
3209 }
else if (
auto *TD =
3210 dyn_cast<VarTemplatePartialSpecializationDecl>(
Template)) {
3211 TD->getAssociatedConstraints(AssociatedConstraints);
3212 DeducedArgsNeedReplacement = !TD->isClassScopeExplicitSpecialization();
3214 cast<TemplateDecl>(
Template)->getAssociatedConstraints(
3215 AssociatedConstraints);
3218 std::optional<ArrayRef<TemplateArgument>> Innermost;
3221 if (!DeducedArgsNeedReplacement)
3222 Innermost = CanonicalDeducedArgs;
3273 if (CopyDeducedArgs) {
3279 Info.
reset(SugaredDeducedArgumentList, CanonicalDeducedArgumentList);
3295 Info.
FirstArg = Ps[ArgIdx].getArgument();
3302 {},
false, InstCTAI,
3315 while (!Stack.empty()) {
3316 auto &Xs = Stack.back();
3321 auto &
X = Xs.front();
3323 Stack.emplace_back(
X.getPackAsArray());
3324 Xs = Xs.drop_front();
3327 assert(!
X.isNull());
3334 auto [Ps,
P] = take(PsStack);
3335 auto [As, A] = take(AsStack);
3336 if (
P.isNull() && A.isNull())
3339 PA = A.isPackExpansion() ? A.getPackExpansionPattern() : A;
3341 if (!
P.isPackExpansion() && !A.isPackExpansion()) {
3343 (AsStack.empty() ? As.end() : AsStack.back().begin()) -
3349 if (
P.isPackExpansion()) {
3350 Ps = Ps.drop_front();
3353 if (A.isPackExpansion()) {
3354 As = As.drop_front();
3358 Ps = Ps.drop_front(
P.isPackExpansion() ? 0 : 1);
3359 As = As.drop_front(A.isPackExpansion() && !
P.isPackExpansion() ? 0 : 1);
3361 assert(PsStack.empty());
3362 assert(AsStack.empty());
3381 for (
unsigned I = 0, N = Ps.size(); I != N; ++I)
3386 Info, CopyDeducedArgs);
3421template <
typename T>
3422static std::enable_if_t<IsPartialSpecialization<T>::value,
3427 if (Partial->isInvalidDecl())
3446 Deduced.resize(Partial->getTemplateParameters()->size());
3448 S, Partial->getTemplateParameters(),
3449 Partial->getTemplateArgs().asArray(), TemplateArgs, Info, Deduced,
3451 PackFold::ParameterToArgument,
3464 Result = ::FinishTemplateArgumentDeduction(
3465 S, Partial, Partial->getTemplateParameters(),
3466 Partial->getSpecializedTemplate(),
3468 Partial->getTemplateArgsAsWritten()->arguments(), TemplateArgs, Deduced,
3485 return ::DeduceTemplateArguments(*
this, Partial, TemplateArgs, Info);
3491 return ::DeduceTemplateArguments(*
this, Partial, TemplateArgs, Info);
3501 if (
const auto *CTD = dyn_cast<ClassTemplateDecl>(TD)) {
3504 }
else if (
const auto *
AliasTemplate = dyn_cast<TypeAliasTemplateDecl>(TD)) {
3505 PType =
AliasTemplate->getTemplatedDecl()->getUnderlyingType();
3507 assert(
false &&
"Expected a class or alias template");
3526 return DeducedResult;
3536 Result = ::FinishTemplateArgumentDeduction(*this, TD, Deduced, Info);
3552 return Spec->getTemplateName().getAsTemplateDecl() !=
nullptr;
3562 if (isa<InjectedClassNameType>(
T.getCanonicalType()))
3578 if (ExplicitTemplateArgs.
size() == 0) {
3582 ParamTypes.push_back(
P->getType());
3612 ExplicitTemplateArgs, {},
3617 if (Index >= TemplateParams->
size())
3630 CanonicalExplicitArgumentList);
3642 unsigned PartiallySubstitutedPackIndex = -1u;
3650 if (!Expansions || Arg.
pack_size() < *Expansions) {
3660 assert(Proto &&
"Function template does not have a prototype?");
3668 SugaredExplicitArgumentList->
asArray(),
3678 nullptr, ExtParamInfos))
3694 ThisContext =
Method->getParent();
3695 ThisTypeQuals =
Method->getMethodQualifiers();
3709 Diag(
Function->getLocation(), diag::err_kern_type_not_void_return)
3720 nullptr, ExtParamInfos))
3744 Deduced.reserve(TemplateParams->
size());
3745 for (
unsigned I = 0, N = SugaredExplicitArgumentList->
size(); I != N; ++I) {
3747 if (I == PartiallySubstitutedPackIndex)
3750 Deduced.push_back(Arg);
3818 if (AQuals == DeducedAQuals) {
3836 bool ObjCLifetimeConversion =
false;
3839 ObjCLifetimeConversion) ||
3885 if (PD->isParameterPack()) {
3888 unsigned NumExpansions = NumArgs ? *NumArgs : 1;
3889 if (Idx + NumExpansions >
ParamIdx)
3891 Idx += NumExpansions;
3894 return std::nullopt;
3899 llvm_unreachable(
"parameter index would not be produced from template");
3911 return isa<CXXConstructorDecl>(
D)
3912 ? cast<CXXConstructorDecl>(
D)->getExplicitSpecifier()
3913 : cast<CXXConversionDecl>(
D)->getExplicitSpecifier();
3916 isa<CXXConstructorDecl>(
D)
3917 ? cast<CXXConstructorDecl>(
D)->setExplicitSpecifier(ES)
3918 : cast<CXXConversionDecl>(
D)->setExplicitSpecifier(ES);
3951 bool ForOverloadSetAddressResolution,
3952 llvm::function_ref<
bool(
bool)> CheckNonDependent) {
3972 bool IsIncomplete =
false;
3977 NumExplicitlySpecified, PartialOverloading ? &IsIncomplete :
nullptr);
3986 Info.
reset(SugaredDeducedArgumentList, CanonicalDeducedArgumentList);
3995 if (CheckNonDependent(
true))
4007 if (!IsLambda && !IsIncomplete) {
4028 if (CheckNonDependent(
false))
4045 CanonicalDeducedArgumentList &&
4065 if (IsLambda && !IsIncomplete) {
4081 if (isa<CXXConstructorDecl, CXXConversionDecl>(
Specialization)) {
4090 if (OriginalCallArgs) {
4095 llvm::SmallDenseMap<std::pair<unsigned, QualType>,
QualType> DeducedATypes;
4096 for (
unsigned I = 0, N = OriginalCallArgs->size(); I != N; ++I) {
4100 unsigned ExplicitOffset =
4102 !ForOverloadSetAddressResolution)
4123 if (CacheEntry.
isNull()) {
4132 DeducedA = CacheEntry;
4147 auto [Pos, Inserted] =
4161 if (S.
getLangOpts().CPlusPlus14 && Fn->getReturnType()->isUndeducedType() &&
4166 if (
Method->isImplicitObjectMemberFunction()) {
4173 Fn->getType(), std::nullopt,
Method->getParent());
4187 bool ParamWasReference,
4196 if (ParamWasReference)
4255 if (ArgType.
isNull())
continue;
4275 Deduced(TemplateParams->
size());
4278 S, TemplateParams, ParamType, ArgType, Info, Deduced, TDF,
4279 PartialOrderingKind::None,
false,
4322 assert(Arg &&
"expected a non-null arg expression");
4324 ParamRefType !=
nullptr, FailedTSC);
4332 assert(Arg &&
"expected a non-null arg expression");
4406 bool DecomposedParam,
unsigned ArgIdx,
unsigned TDF,
4431 ElTy = ArrTy->getElementType();
4441 if (isa<DesignatedInitExpr>(
E))
4448 S, TemplateParams, 0, ElTy,
E->
getType(),
4450 OriginalCallArgs,
true, ArgIdx, TDF);
4458 if (
auto *DependentArrTy = dyn_cast_or_null<DependentSizedArrayType>(ArrTy)) {
4461 Info, DependentArrTy->getSizeExpr())) {
4470 S, TemplateParams, NTTP, llvm::APSInt(Size),
T,
4471 true, Info,
false, Deduced,
4490 bool DecomposedParam,
unsigned ArgIdx,
unsigned TDF,
4493 QualType OrigParamType = ParamType;
4498 S, TemplateParams, FirstInnerIndex, ParamType, ArgType,
4499 ArgClassification, Arg, TDF, FailedTSC))
4503 if (
InitListExpr *ILE = dyn_cast_if_present<InitListExpr>(Arg))
4505 Deduced, OriginalCallArgs, ArgIdx, TDF);
4513 OriginalCallArgs.push_back(
4516 S, TemplateParams, ParamType, ArgType, Info, Deduced, TDF,
4517 PartialOrderingKind::None,
false,
4525 bool PartialOverloading,
bool AggregateDeductionCandidate,
4528 bool ForOverloadSetAddressResolution,
4534 unsigned NumParams =
Function->getNumParams();
4535 bool HasExplicitObject =
false;
4536 int ExplicitObjectOffset = 0;
4544 if (!ForOverloadSetAddressResolution &&
4545 Function->hasCXXExplicitFunctionObjectParameter()) {
4546 HasExplicitObject =
true;
4547 ExplicitObjectOffset = 1;
4556 if (Args.size() <
Function->getMinRequiredExplicitArguments() &&
4557 !PartialOverloading)
4560 PartialOverloading)) {
4562 if (Proto->isTemplateVariadic())
4564 else if (!Proto->isVariadic())
4575 unsigned NumExplicitlySpecified = 0;
4576 if (ExplicitTemplateArgs) {
4579 Result = SubstituteExplicitTemplateArguments(
4580 FunctionTemplate, *ExplicitTemplateArgs, Deduced, ParamTypes, nullptr,
4586 NumExplicitlySpecified = Deduced.size();
4589 for (
unsigned I = 0; I != NumParams; ++I)
4590 ParamTypes.push_back(
Function->getParamDecl(I)->getType());
4596 auto DeduceCallArgument = [&](
QualType ParamType,
unsigned ArgIdx,
4597 bool ExplicitObjectArgument) {
4605 if (ExplicitObjectArgument) {
4608 *
this, TemplateParams, FirstInnerIndex, ParamType, ObjectType,
4609 ObjectClassification,
4610 nullptr, Info, Deduced, OriginalCallArgs,
4616 *
this, TemplateParams, FirstInnerIndex, ParamType,
4617 Args[ArgIdx]->getType(), Args[ArgIdx]->Classify(
getASTContext()),
4618 Args[ArgIdx], Info, Deduced, OriginalCallArgs,
false,
4623 Deduced.resize(TemplateParams->
size());
4625 for (
unsigned ParamIdx = 0, NumParamTypes = ParamTypes.size(), ArgIdx = 0;
4630 dyn_cast<PackExpansionType>(ParamType);
4631 if (!ParamExpansion) {
4633 if (ArgIdx >= Args.size() && !(HasExplicitObject &&
ParamIdx == 0))
4636 ParamTypesForArgChecking.push_back(ParamType);
4638 if (
ParamIdx == 0 && HasExplicitObject) {
4642 if (
auto Result = DeduceCallArgument(ParamType, 0,
4649 if (
auto Result = DeduceCallArgument(ParamType, ArgIdx++,
4657 bool IsTrailingPack =
ParamIdx + 1 == NumParamTypes;
4660 PackDeductionScope PackScope(*
this, TemplateParams, Deduced, Info,
4662 AggregateDeductionCandidate && IsTrailingPack);
4680 if (IsTrailingPack || PackScope.hasFixedArity()) {
4681 for (; ArgIdx < Args.size() && PackScope.hasNextElement();
4682 PackScope.nextPackElement(), ++ArgIdx) {
4683 ParamTypesForArgChecking.push_back(ParamPattern);
4684 if (
auto Result = DeduceCallArgument(ParamPattern, ArgIdx,
4694 if (NumExpansions && !PackScope.isPartiallyExpanded()) {
4695 for (
unsigned I = 0; I != *NumExpansions && ArgIdx < Args.size();
4697 ParamTypesForArgChecking.push_back(ParamPattern);
4700 PackScope.nextPackElement();
4702 }
else if (!IsTrailingPack && !PackScope.isPartiallyExpanded() &&
4703 PackScope.isDeducedFromEarlierParameter()) {
4717 PackScope.getSavedPackSizeIfAllEqual();
4718 if (!ArgPosAfterSubstitution)
4721 unsigned PackArgEnd = ArgIdx + *ArgPosAfterSubstitution;
4722 for (; ArgIdx < PackArgEnd && ArgIdx < Args.size(); ArgIdx++) {
4723 ParamTypesForArgChecking.push_back(ParamPattern);
4725 DeduceCallArgument(ParamPattern, ArgIdx,
4730 PackScope.nextPackElement();
4737 if (
auto Result = PackScope.finish();
4748 Result = FinishTemplateArgumentDeduction(
4749 FunctionTemplate, Deduced, NumExplicitlySpecified, Specialization, Info,
4750 &OriginalCallArgs, PartialOverloading, PartialOrdering,
4751 ForOverloadSetAddressResolution,
4752 [&, CallingCtx](bool OnlyInitializeNonUserDefinedConversions) {
4753 ContextRAII SavedContext(*this, CallingCtx);
4754 return CheckNonDependent(ParamTypesForArgChecking,
4755 OnlyInitializeNonUserDefinedConversions);
4763 bool AdjustExceptionSpec) {
4764 if (ArgFunctionType.
isNull())
4765 return ArgFunctionType;
4770 bool Rebuild =
false;
4773 if (EPI.ExtInfo.getCC() != CC) {
4774 EPI.
ExtInfo = EPI.ExtInfo.withCallingConv(CC);
4778 bool NoReturn = FunctionTypeP->getNoReturnAttr();
4779 if (EPI.ExtInfo.getNoReturn() != NoReturn) {
4780 EPI.ExtInfo = EPI.ExtInfo.withNoReturn(NoReturn);
4784 if (AdjustExceptionSpec && (FunctionTypeP->hasExceptionSpec() ||
4786 EPI.ExceptionSpec = FunctionTypeP->getExtProtoInfo().ExceptionSpec;
4791 return ArgFunctionType;
4801 bool IsAddressOfFunction) {
4813 unsigned NumExplicitlySpecified = 0;
4815 if (ExplicitTemplateArgs) {
4818 Result = SubstituteExplicitTemplateArguments(
4819 FunctionTemplate, *ExplicitTemplateArgs, Deduced, ParamTypes,
4820 &FunctionType, Info);
4825 NumExplicitlySpecified = Deduced.size();
4831 if (!IsAddressOfFunction)
4836 std::optional<EnterExpressionEvaluationContext>
Unevaluated(
4840 Deduced.resize(TemplateParams->
size());
4844 bool HasDeducedReturnType =
false;
4846 Function->getReturnType()->getContainedAutoType()) {
4848 HasDeducedReturnType =
true;
4856 *
this, TemplateParams,
FunctionType, ArgFunctionType, Info, Deduced,
4857 TDF, PartialOrderingKind::None,
false,
4865 Result = FinishTemplateArgumentDeduction(
4866 FunctionTemplate, Deduced, NumExplicitlySpecified, Specialization, Info,
4868 true, IsAddressOfFunction);
4875 if (HasDeducedReturnType && IsAddressOfFunction &&
4897 if (!IsAddressOfFunction) {
4903 if (HasDeducedReturnType) {
4912 if (!ArgFunctionType.
isNull()) {
4914 SpecializationType, ArgFunctionType)
4916 SpecializationType, ArgFunctionType)) {
4937 bool IsReferenceP =
P->isReferenceType();
4944 P = PRef->getPointeeType();
4954 if (!IsReferenceP) {
4956 P =
P.getUnqualifiedType();
4963 assert(!A->
isReferenceType() &&
"Reference types were handled above");
4968 if (
P->isArrayType())
4973 else if (
P->isFunctionType())
4978 P =
P.getUnqualifiedType();
5000 Deduced.resize(TemplateParams->
size());
5029 ParamType, ObjectType, ObjectClassification,
5030 nullptr, Info, Deduced, OriginalCallArgs,
5037 *
this, TemplateParams,
P, A, Info, Deduced, TDF,
5038 PartialOrderingKind::None,
false,
5049 Result = FinishTemplateArgumentDeduction(
5050 ConversionTemplate, Deduced, 0, ConversionSpecialized, Info,
5051 &OriginalCallArgs, false,
5054 Specialization = cast_or_null<CXXConversionDecl>(ConversionSpecialized);
5063 bool IsAddressOfFunction) {
5066 IsAddressOfFunction);
5070 struct DependentAuto {
bool IsPack; };
5074 class SubstituteDeducedTypeTransform :
5077 bool ReplacementIsPack;
5082 SubstituteDeducedTypeTransform(
Sema &SemaRef, DependentAuto DA)
5084 ReplacementIsPack(DA.IsPack), UseTypeSugar(
true) {}
5086 SubstituteDeducedTypeTransform(
Sema &SemaRef,
QualType Replacement,
5087 bool UseTypeSugar =
true)
5089 Replacement(Replacement), ReplacementIsPack(
false),
5090 UseTypeSugar(UseTypeSugar) {}
5093 assert(isa<TemplateTypeParmType>(Replacement) &&
5094 "unexpected unsugared replacement kind");
5112 return TransformDesugared(TLB, TL);
5114 QualType Result = SemaRef.Context.getAutoType(
5123 QualType TransformDeducedTemplateSpecializationType(
5126 return TransformDesugared(TLB, TL);
5128 QualType Result = SemaRef.Context.getDeducedTemplateSpecializationType(
5130 Replacement, Replacement.isNull());
5150 return inherited::TransformExceptionSpec(
Loc, ESI, Exceptions, Changed);
5158 return TransformType(TLB, TL);
5174 Deduced,
TypeLoc.getNameLoc())));
5175 for (
unsigned I = 0,
C =
TypeLoc.getNumArgs(); I !=
C; ++I)
5205 llvm::raw_string_ostream OS(Buf);
5206 OS <<
"'" <<
Concept->getName();
5207 if (
TypeLoc.hasExplicitTemplateArgs()) {
5210 Type.getTypeConstraintConcept()->getTemplateParameters());
5214 diag::err_placeholder_constraints_not_satisfied)
5225 bool IgnoreConstraints,
5228 if (
Init->containsErrors())
5241 DependentAuto DependentResult = {
5244 if (!DependentDeduction &&
5246 Init->containsUnexpandedParameterPack())) {
5247 Result = SubstituteDeducedTypeTransform(*
this, DependentResult).Apply(
Type);
5248 assert(!
Result.isNull() &&
"substituting DependentTy can't fail");
5253 auto *String = dyn_cast<StringLiteral>(
Init);
5255 Diag(
Type.getBeginLoc(), diag::ext_c23_auto_non_plain_identifier);
5257 Result = SubstituteDeducedTypeTransform(*
this, DependentResult).Apply(TL);
5258 assert(!
Result.isNull() &&
"substituting DependentTy can't fail");
5264 Diag(
Type.getBeginLoc(), diag::ext_c23_auto_non_plain_identifier);
5267 auto *InitList = dyn_cast<InitListExpr>(
Init);
5269 Diag(
Init->getBeginLoc(), diag::err_auto_init_list_from_c)
5281 if (
Init->isTypeDependent()) {
5283 SubstituteDeducedTypeTransform(*
this, DependentResult).Apply(
Type);
5284 assert(!
Result.isNull() &&
"substituting DependentTy can't fail");
5296 Diag(
Init->getBeginLoc(), diag::err_decltype_auto_initializer_list);
5309 nullptr,
false,
false,
false);
5323 for (
Expr *
Init : InitList->inits()) {
5326 if (isa<DesignatedInitExpr>(
Init))
5329 *
this, TemplateParamsSt.get(), 0, TemplArg,
Init->getType(),
5338 <<
Init->getSourceRange();
5341 return DeductionFailed(TDK);
5346 DeducedFromInitRange =
Init->getSourceRange();
5350 Diag(
Loc, diag::err_auto_bitfield);
5354 SubstituteDeducedTypeTransform(*
this, TemplArg).Apply(
Type);
5355 assert(!FuncParam.
isNull() &&
5356 "substituting template parameter for 'auto' failed");
5358 *
this, TemplateParamsSt.get(), 0, FuncParam,
Init->getType(),
5361 false, 0, 0, FailedTSC);
5363 return DeductionFailed(TDK);
5400 assert((
bool)InitList == OriginalArg.DecomposedParam &&
5401 "decomposed non-init-list in auto deduction?");
5406 return DeductionFailed(TDK);
5416 return SubstituteDeducedTypeTransform(*
this, TypeToReplaceAuto)
5417 .TransformType(TypeWithAuto);
5423 return SubstituteDeducedTypeTransform(*
this, TypeToReplaceAuto)
5424 .TransformType(TypeWithAuto);
5428 return SubstituteDeducedTypeTransform(*
this, DependentAuto{
false})
5429 .TransformType(TypeWithAuto);
5434 return SubstituteDeducedTypeTransform(*
this, DependentAuto{
false})
5435 .TransformType(TypeWithAuto);
5440 return SubstituteDeducedTypeTransform(*
this, TypeToReplaceAuto,
5442 .TransformType(TypeWithAuto);
5447 return SubstituteDeducedTypeTransform(*
this, TypeToReplaceAuto,
5449 .TransformType(TypeWithAuto);
5454 if (isa<InitListExpr>(
Init))
5457 ? diag::err_init_capture_deduction_failure_from_init_list
5458 : diag::err_auto_var_deduction_failure_from_init_list)
5462 VDecl->
isInitCapture() ? diag::err_init_capture_deduction_failure
5463 : diag::err_auto_var_deduction_failure)
5465 <<
Init->getSourceRange();
5497 "failed to deduce lambda return type");
5524 Diag(
Loc, diag::err_auto_fn_used_before_defined) << FD;
5528 return StillUndeduced;
5571 assert(
Method && !
Method->isExplicitObjectMemberFunction() &&
5572 "expected a member function with no explicit object parameter");
5589 bool IsIncompleteSubstitution =
false;
5597 bool IsDeductionGuide = isa<CXXDeductionGuideDecl>(FTD->
getTemplatedDecl());
5598 if (IsDeductionGuide) {
5600 P = Injected->getOriginalDecl()->getCanonicalTemplateSpecializationType(
5605 if (InstP.
isNull() && !IsIncompleteSubstitution)
5607 if (!CheckConsistency)
5609 if (IsIncompleteSubstitution)
5614 if (
auto *PA = dyn_cast<PackExpansionType>(A);
5615 PA && !isa<PackExpansionType>(InstP))
5616 A = PA->getPattern();
5619 if (IsDeductionGuide) {
5621 T1 = Injected->getOriginalDecl()->getCanonicalTemplateSpecializationType(
5624 T2 = Injected->getOriginalDecl()->getCanonicalTemplateSpecializationType(
5646 bool IsIncomplete =
false;
5662 Info.
reset(SugaredDeducedArgumentList, CanonicalDeducedArgumentList);
5687 assert(Proto1 && Proto2 &&
"Function templates must have prototypes");
5703 Proto1->
isVariadic() == Proto2->isVariadic() &&
5704 "shouldn't partial order functions with different qualifiers in a "
5705 "context where the function type is used");
5707 assert(Args1.empty() && Args2.empty() &&
5708 "Only call context should have arguments");
5710 Args2 = Proto2->getParamTypes();
5717 bool HasDeducedAnyParamFromReturnType =
false;
5720 S, TemplateParams, Proto2->getReturnType(), Proto1->
getReturnType(),
5721 Info, Deduced,
TDF_None, PartialOrderingKind::Call,
5723 &HasDeducedAnyParamFromReturnType) !=
5728 llvm::SmallBitVector HasDeducedParam;
5730 HasDeducedParam.resize(Args2.size());
5732 TDF_None, PartialOrderingKind::Call,
5734 &HasDeducedParam) !=
5746 bool AtLeastAsSpecialized;
5748 AtLeastAsSpecialized =
5749 ::FinishTemplateArgumentDeduction(
5750 S, FT2, Deduced, Info,
5751 [&](Sema &S, FunctionTemplateDecl *FTD,
5752 ArrayRef<TemplateArgument> DeducedArgs) {
5757 if (TPOC != TPOC_Call) {
5758 if (auto TDR = ::CheckDeductionConsistency(
5759 S, FTD, std::nullopt,
5760 Proto2->getReturnType(), Proto1->getReturnType(),
5762 HasDeducedAnyParamFromReturnType);
5763 TDR != TemplateDeductionResult::Success)
5767 if (TPOC == TPOC_Conversion)
5768 return TemplateDeductionResult::Success;
5770 return ::DeduceForEachType(
5771 S, TemplateParams, Args2, Args1, Info, Deduced,
5772 PartialOrderingKind::Call, true,
5773 [&](Sema &S, TemplateParameterList *, int ParamIdx,
5774 UnsignedOrNone ArgIdx, QualType P, QualType A,
5775 TemplateDeductionInfo &Info,
5776 SmallVectorImpl<DeducedTemplateArgument> &Deduced,
5777 PartialOrderingKind) {
5778 if (ArgIdx && *ArgIdx >= static_cast<unsigned>(Args1Offset))
5779 ArgIdx = *ArgIdx - Args1Offset;
5781 ArgIdx = std::nullopt;
5782 return ::CheckDeductionConsistency(
5783 S, FTD, ArgIdx, P, A, DeducedArgs,
5784 HasDeducedParam[ParamIdx]);
5788 if (!AtLeastAsSpecialized)
5797 unsigned ArgIdx = 0, NumArgs = Deduced.size();
5798 for (; ArgIdx != NumArgs; ++ArgIdx)
5799 if (Deduced[ArgIdx].isNull())
5802 if (ArgIdx == NumArgs) {
5809 llvm::SmallBitVector UsedParameters(TemplateParams->size());
5812 for (
unsigned I = 0, N = Args2.size(); I != N; ++I)
5814 TemplateParams->getDepth(), UsedParameters);
5820 TemplateParams->getDepth(), UsedParameters);
5846 false, TemplateParams->getDepth(), UsedParameters);
5850 for (; ArgIdx != NumArgs; ++ArgIdx)
5853 if (Deduced[ArgIdx].isNull() && UsedParameters[ArgIdx])
5873 return MoreSpecializedTrailingPackTieBreakerResult::Equal;
5874 assert(As1.size() == As2.size());
5876 unsigned PackSize1 = TA1.
pack_size(), PackSize2 = TA2.pack_size();
5877 bool IsPackExpansion1 =
5879 bool IsPackExpansion2 =
5880 PackSize2 && TA2.pack_elements().back().isPackExpansion();
5881 if (PackSize1 == PackSize2 && IsPackExpansion1 == IsPackExpansion2)
5882 return MoreSpecializedTrailingPackTieBreakerResult::Equal;
5883 if (PackSize1 > PackSize2 && IsPackExpansion1)
5884 return MoreSpecializedTrailingPackTieBreakerResult::More;
5885 if (PackSize1 < PackSize2 && IsPackExpansion2)
5886 return MoreSpecializedTrailingPackTieBreakerResult::Less;
5887 return MoreSpecializedTrailingPackTieBreakerResult::Equal;
5894 bool PartialOverloading) {
5899 bool ShouldConvert1 =
false;
5900 bool ShouldConvert2 =
false;
5901 bool Args1Offset =
false;
5902 bool Args2Offset =
false;
5913 const CXXMethodDecl *Method1 = dyn_cast<CXXMethodDecl>(FD1);
5914 const CXXMethodDecl *Method2 = dyn_cast<CXXMethodDecl>(FD2);
5925 bool NonStaticMethod1 = Method1 && !Method1->isStatic(),
5926 NonStaticMethod2 = Method2 && !Method2->
isStatic();
5929 Params2Begin = Proto2->param_type_begin();
5931 size_t NumComparedArguments = NumCallArguments1;
5934 (NonStaticMethod1 && NonStaticMethod2) ||
5935 (OO !=
OO_None && OO != OO_Call && OO != OO_Subscript)) {
5937 NonStaticMethod1 && !Method1->hasCXXExplicitFunctionObjectParameter();
5940 NumComparedArguments += 1;
5942 if (ShouldConvert1) {
5946 : Proto2->param_type_begin()[0]->isRValueReferenceType();
5949 RawObj1Ty, IsRValRef2);
5950 Args1.push_back(Obj1Ty);
5953 if (ShouldConvert2) {
5956 ? Method1->getRefQualifier() ==
RQ_RValue
5960 RawObj2Ty, IsRValRef1);
5961 Args2.push_back(Obj2Ty);
5965 if (NonStaticMethod1 && Method1->hasCXXExplicitFunctionObjectParameter())
5970 Args1.insert(Args1.end(), Params1Begin, Proto1->
param_type_end());
5971 Args2.insert(Args2.end(), Params2Begin, Proto2->param_type_end());
5976 Args1.resize(std::min(Args1.size(), NumComparedArguments));
5977 Args2.resize(std::min(Args2.size(), NumComparedArguments));
5980 std::reverse(Args2.begin(), Args2.end());
5982 assert(!
Reversed &&
"Only call context could have reversed arguments");
5985 Args2, Args2Offset);
5987 Args1, Args1Offset);
5991 if (Better1 != Better2)
5992 return Better1 ? FT1 : FT2;
5994 if (!Better1 && !Better2)
6003 Param1.reserve(FD1->
param_size() + ShouldConvert1);
6005 Param1.push_back(Obj1Ty);
6007 Param1.push_back(
P->getType());
6010 Param2.reserve(FD2->
param_size() + ShouldConvert2);
6012 Param2.push_back(Obj2Ty);
6014 Param2.push_back(
P->getType());
6016 unsigned NumParams1 = Param1.size();
6017 unsigned NumParams2 = Param2.size();
6023 if (Variadic1 != Variadic2) {
6024 if (Variadic1 && NumParams1 > NumParams2)
6026 if (Variadic2 && NumParams2 > NumParams1)
6033 for (
int i = 0, e = std::min(NumParams1, NumParams2);
6034 !PartialOverloading && i < e; ++i) {
6035 QualType T1 = Param1[i].getCanonicalType();
6036 QualType T2 = Param2[i].getCanonicalType();
6037 auto *TST1 = dyn_cast<TemplateSpecializationType>(T1);
6038 auto *TST2 = dyn_cast<TemplateSpecializationType>(T2);
6042 case MoreSpecializedTrailingPackTieBreakerResult::Less:
6044 case MoreSpecializedTrailingPackTieBreakerResult::More:
6046 case MoreSpecializedTrailingPackTieBreakerResult::Equal:
6050 "unknown MoreSpecializedTrailingPackTieBreakerResult value");
6069 if (TPL1->
size() != TPL2->
size() || NumParams1 != NumParams2)
6085 for (
unsigned i = 0; i < NumParams1; ++i)
6101 bool AtLeastAsConstrained1, AtLeastAsConstrained2;
6106 if (AtLeastAsConstrained1 == AtLeastAsConstrained2)
6108 return AtLeastAsConstrained1 ? FT1 : FT2;
6116 bool Complain,
QualType TargetType) {
6117 if (SpecBegin == SpecEnd) {
6125 if (SpecBegin + 1 == SpecEnd)
6132 = cast<FunctionDecl>(*Best)->getPrimaryTemplate();
6133 assert(BestTemplate &&
"Not a function template specialization?");
6136 = cast<FunctionDecl>(*I)->getPrimaryTemplate();
6137 assert(Challenger &&
"Not a function template specialization?");
6142 BestTemplate = Challenger;
6151 = cast<FunctionDecl>(*I)->getPrimaryTemplate();
6173 const auto *FD = cast<FunctionDecl>(*I);
6175 FD->getPrimaryTemplate()->getTemplateParameters(),
6176 *FD->getTemplateSpecializationArgs());
6177 if (!TargetType.
isNull())
6179 Diag((*I)->getLocation(), PD);
6189 "not for function templates");
6191 (isa<CXXConversionDecl, CXXConstructorDecl>(FD1)));
6193 (isa<CXXConversionDecl, CXXConstructorDecl>(FD2)));
6206 bool AtLeastAsConstrained1, AtLeastAsConstrained2;
6211 if (AtLeastAsConstrained1 == AtLeastAsConstrained2)
6213 return AtLeastAsConstrained1 ? FD1 : FD2;
6225template <
typename TemplateLikeDecl>
6227 TemplateLikeDecl *P2,
6257 Deduced.resize(P2->getTemplateParameters()->size());
6259 S, P2->getTemplateParameters(), T2, T1, Info, Deduced,
TDF_None,
6260 PartialOrderingKind::Call,
false,
6272 Ps = cast<TemplateSpecializationType>(T2)->template_arguments(),
6273 As = cast<TemplateSpecializationType>(T1)->template_arguments();
6279 Result = ::FinishTemplateArgumentDeduction(
6280 S, P2, P2->getTemplateParameters(), Template,
6281 true, Ps, As, Deduced, Info,
6298 template <
typename T1,
typename T2,
6299 std::enable_if_t<std::is_same_v<T1, T2>,
bool> =
true>
6300 T2 *operator()(T1 *, T2 *P2) {
6303 template <
typename T1,
typename T2,
6304 std::enable_if_t<!std::is_same_v<T1, T2>,
bool> =
true>
6305 T1 *operator()(T1 *, T2 *) {
6311struct TemplateArgumentListAreEqual {
6313 TemplateArgumentListAreEqual(
ASTContext &Ctx) : Ctx(Ctx) {}
6315 template <
typename T1,
typename T2,
6316 std::enable_if_t<std::is_same_v<T1, T2>,
bool> =
true>
6317 bool operator()(T1 *PS1, T2 *PS2) {
6319 Args2 = PS2->getTemplateArgs().asArray();
6321 for (
unsigned I = 0,
E = Args1.size(); I <
E; ++I) {
6325 llvm::FoldingSetNodeID IDA, IDB;
6326 Args1[I].Profile(IDA, Ctx);
6327 Args2[I].Profile(IDB, Ctx);
6334 template <
typename T1,
typename T2,
6335 std::enable_if_t<!std::is_same_v<T1, T2>,
bool> =
true>
6336 bool operator()(T1 *Spec, T2 *Primary) {
6338 Args2 = Primary->getInjectedTemplateArgs(Ctx);
6340 for (
unsigned I = 0,
E = Args1.size(); I <
E; ++I) {
6344 llvm::FoldingSetNodeID IDA, IDB;
6345 Args1[I].Profile(IDA, Ctx);
6379template <
typename TemplateLikeDecl,
typename PrimaryDel>
6380static TemplateLikeDecl *
6383 constexpr bool IsMoreSpecialThanPrimaryCheck =
6384 !std::is_same_v<TemplateLikeDecl, PrimaryDel>;
6387 if constexpr (IsMoreSpecialThanPrimaryCheck)
6390 P2T = P2->getSpecializedTemplate();
6393 if (IsMoreSpecialThanPrimaryCheck && !Better1)
6397 P1->getSpecializedTemplate(), Info);
6398 if (IsMoreSpecialThanPrimaryCheck && !Better2)
6404 if (Better1 != Better2)
6405 return Better1 ? P1 : GetP2()(P1, P2);
6407 if (!Better1 && !Better2)
6411 cast<TemplateSpecializationType>(T1),
6412 cast<TemplateSpecializationType>(T2))) {
6413 case MoreSpecializedTrailingPackTieBreakerResult::Less:
6415 case MoreSpecializedTrailingPackTieBreakerResult::More:
6416 return GetP2()(P1, P2);
6417 case MoreSpecializedTrailingPackTieBreakerResult::Equal:
6445 if (!TemplateArgumentListAreEqual(S.
getASTContext())(P1, P2))
6449 P1->getAssociatedConstraints(AC1);
6450 P2->getAssociatedConstraints(AC2);
6451 bool AtLeastAsConstrained1, AtLeastAsConstrained2;
6453 (IsMoreSpecialThanPrimaryCheck && !AtLeastAsConstrained1))
6457 if (AtLeastAsConstrained1 == AtLeastAsConstrained2)
6459 return AtLeastAsConstrained1 ? P1 : GetP2()(P1, P2);
6494 "the partial specializations being compared should specialize"
6495 " the same template.");
6563 for (
unsigned I = 0, N =
P->size(); I != N; ++I) {
6572 Arg,
QualType(),
P->getParam(I)->getLocation()));
6588 if (StrictPackMatch)
6595 Deduced.resize(A->
size());
6609 *
this, A, AArgs, PArgs, Info, Deduced,
6615 *StrictPackMatch =
true;
6619 Diag(AArg->
getLocation(), diag::err_template_param_list_different_arity)
6620 << (A->
size() >
P->size()) <<
true
6629 diag::err_inconsistent_deduction)
6650 llvm_unreachable(
"Unexpected Result");
6655 TDK = ::FinishTemplateArgumentDeduction(
6656 *this, AArg, AArg->getTemplateParameters(), AArg, PartialOrdering,
6657 AArgs, PArgs, Deduced, Info, false);
6667 assert(PArg->
isInvalidDecl() &&
"Unexpected NonDeducedMismatch");
6691 llvm_unreachable(
"Unexpected Result");
6693 llvm_unreachable(
"Unexpected TDK");
6698 llvm::SmallBitVector &
Used;
6701 MarkUsedTemplateParameterVisitor(llvm::SmallBitVector &
Used,
6706 if (
T->getDepth() == Depth)
6707 Used[
T->getIndex()] =
true;
6712 if (
auto *TTP = llvm::dyn_cast_or_null<TemplateTemplateParmDecl>(
6714 if (TTP->getDepth() == Depth)
6715 Used[TTP->getIndex()] =
true;
6721 if (
auto *NTTP = dyn_cast<NonTypeTemplateParmDecl>(
E->getDecl()))
6722 if (NTTP->getDepth() == Depth)
6723 Used[NTTP->getIndex()] =
true;
6730 if (TTP->getDepth() == Depth)
6731 Used[TTP->getIndex()] =
true;
6748 llvm::SmallBitVector &
Used) {
6750 MarkUsedTemplateParameterVisitor(
Used, Depth)
6751 .TraverseStmt(
const_cast<Expr *
>(
E));
6757 E = Expansion->getPattern();
6760 if (
const auto *ULE = dyn_cast<UnresolvedLookupExpr>(
E);
6763 Used[TTP->getIndex()] =
true;
6786 bool OnlyDeduced,
unsigned Depth,
6787 llvm::SmallBitVector &
Used) {
6801 llvm::SmallBitVector &
Used) {
6804 = dyn_cast<TemplateTemplateParmDecl>(
Template)) {
6805 if (TTP->getDepth() == Depth)
6806 Used[TTP->getIndex()] =
true;
6825 llvm::SmallBitVector &
Used) {
6843 case Type::BlockPointer:
6851 case Type::LValueReference:
6852 case Type::RValueReference:
6860 case Type::MemberPointer: {
6866 OnlyDeduced, Depth,
Used);
6870 case Type::DependentSizedArray:
6872 cast<DependentSizedArrayType>(
T)->getSizeExpr(),
6873 OnlyDeduced, Depth,
Used);
6877 case Type::ConstantArray:
6878 case Type::IncompleteArray:
6879 case Type::ArrayParameter:
6881 cast<ArrayType>(
T)->getElementType(),
6882 OnlyDeduced, Depth,
Used);
6885 case Type::ExtVector:
6887 cast<VectorType>(
T)->getElementType(),
6888 OnlyDeduced, Depth,
Used);
6891 case Type::DependentVector: {
6892 const auto *VecType = cast<DependentVectorType>(
T);
6899 case Type::DependentSizedExtVector: {
6901 = cast<DependentSizedExtVectorType>(
T);
6909 case Type::DependentAddressSpace: {
6911 cast<DependentAddressSpaceType>(
T);
6913 OnlyDeduced, Depth,
Used);
6916 OnlyDeduced, Depth,
Used);
6920 case Type::ConstantMatrix: {
6927 case Type::DependentSizedMatrix: {
6938 case Type::FunctionProto: {
6942 for (
unsigned I = 0, N = Proto->
getNumParams(); I != N; ++I) {
6947 if (!OnlyDeduced || I + 1 == N ||
6965 case Type::TemplateTypeParm: {
6972 case Type::SubstTemplateTypeParmPack: {
6974 = cast<SubstTemplateTypeParmPackType>(
T);
6981 case Type::SubstBuiltinTemplatePack: {
6983 OnlyDeduced, Depth,
Used);
6987 case Type::InjectedClassName:
6988 T = cast<InjectedClassNameType>(
T)
6990 ->getCanonicalTemplateSpecializationType(Ctx);
6993 case Type::TemplateSpecialization: {
6995 = cast<TemplateSpecializationType>(
T);
7015 cast<ComplexType>(
T)->getElementType(),
7016 OnlyDeduced, Depth,
Used);
7022 cast<AtomicType>(
T)->getValueType(),
7023 OnlyDeduced, Depth,
Used);
7026 case Type::DependentName:
7029 cast<DependentNameType>(
T)->getQualifier(),
7030 OnlyDeduced, Depth,
Used);
7033 case Type::DependentTemplateSpecialization: {
7047 = cast<DependentTemplateSpecializationType>(
T);
7051 OnlyDeduced, Depth,
Used);
7061 OnlyDeduced, Depth,
Used);
7064 case Type::TypeOfExpr:
7067 cast<TypeOfExprType>(
T)->getUnderlyingExpr(),
7068 OnlyDeduced, Depth,
Used);
7071 case Type::Decltype:
7074 cast<DecltypeType>(
T)->getUnderlyingExpr(),
7075 OnlyDeduced, Depth,
Used);
7078 case Type::PackIndexing:
7081 OnlyDeduced, Depth,
Used);
7083 OnlyDeduced, Depth,
Used);
7087 case Type::UnaryTransform:
7091 OnlyDeduced, Depth,
Used);
7094 case Type::PackExpansion:
7096 cast<PackExpansionType>(
T)->getPattern(),
7097 OnlyDeduced, Depth,
Used);
7101 case Type::DeducedTemplateSpecialization:
7103 cast<DeducedType>(
T)->getDeducedType(),
7104 OnlyDeduced, Depth,
Used);
7106 case Type::DependentBitInt:
7108 cast<DependentBitIntType>(
T)->getNumBitsExpr(),
7109 OnlyDeduced, Depth,
Used);
7112 case Type::HLSLAttributedResource:
7114 Ctx, cast<HLSLAttributedResourceType>(
T)->getWrappedType(), OnlyDeduced,
7116 if (cast<HLSLAttributedResourceType>(
T)->hasContainedType())
7118 Ctx, cast<HLSLAttributedResourceType>(
T)->getContainedType(),
7119 OnlyDeduced, Depth,
Used);
7124 case Type::VariableArray:
7125 case Type::FunctionNoProto:
7128 case Type::ObjCInterface:
7129 case Type::ObjCObject:
7130 case Type::ObjCObjectPointer:
7131 case Type::UnresolvedUsing:
7134 case Type::HLSLInlineSpirv:
7135#define TYPE(Class, Base)
7136#define ABSTRACT_TYPE(Class, Base)
7137#define DEPENDENT_TYPE(Class, Base)
7138#define NON_CANONICAL_TYPE(Class, Base) case Type::Class:
7139#include "clang/AST/TypeNodes.inc"
7151 llvm::SmallBitVector &
Used) {
7169 OnlyDeduced, Depth,
Used);
7187 llvm::SmallBitVector &
Used) {
7193 bool OnlyDeduced,
unsigned Depth,
7194 llvm::SmallBitVector &
Used) {
7203 for (
unsigned I = 0, N = TemplateArgs.
size(); I != N; ++I)
7210 llvm::SmallBitVector &
Used) {
7211 for (
unsigned I = 0, N = TemplateArgs.size(); I != N; ++I)
7213 false, Depth,
Used);
7218 llvm::SmallBitVector &Deduced) {
7222 Deduced.resize(TemplateParams->
size());
7225 for (
unsigned I = 0, N =
Function->getNumParams(); I != N; ++I)
7227 true, TemplateParams->
getDepth(), Deduced);
7238 llvm::SmallBitVector Deduced(TemplateParams->
size());
7242 return Deduced.any();
Defines the clang::ASTContext interface.
This file provides some common utility functions for processing Lambda related AST Constructs.
Provides definitions for the various language-specific address spaces.
static Decl::Kind getKind(const Decl *D)
Defines the C++ Decl subclasses, other than those for templates (found in DeclTemplate....
Defines the C++ template declaration subclasses.
Defines the ExceptionSpecificationType enumeration and various utility functions.
Defines the clang::Expr interface and subclasses for C++ expressions.
llvm::DenseSet< const void * > Visited
Forward-declares and imports various common LLVM datatypes that clang wants to use unqualified.
Defines the clang::LangOptions interface.
Implements a partial diagnostic that can be emitted anwyhere in a DiagnosticBuilder stream.
static QualType getUnderlyingType(const SubRegion *R)
static TemplateDeductionResult DeduceNullPtrTemplateArgument(Sema &S, TemplateParameterList *TemplateParams, NonTypeOrVarTemplateParmDecl NTTP, QualType NullPtrType, TemplateDeductionInfo &Info, bool PartialOrdering, SmallVectorImpl< DeducedTemplateArgument > &Deduced, bool *HasDeducedAnyParam)
Deduce the value of the given non-type template parameter from the given null pointer template argume...
static bool ConvertDeducedTemplateArgument(Sema &S, NamedDecl *Param, DeducedTemplateArgument Arg, NamedDecl *Template, TemplateDeductionInfo &Info, bool IsDeduced, Sema::CheckTemplateArgumentInfo &CTAI)
Convert the given deduced template argument and add it to the set of fully-converted template argumen...
static TemplateDeductionResult DeduceTemplateArguments(Sema &S, TemplateParameterList *TemplateParams, ArrayRef< TemplateArgument > Ps, ArrayRef< TemplateArgument > As, TemplateDeductionInfo &Info, SmallVectorImpl< DeducedTemplateArgument > &Deduced, bool NumberOfArgumentsMustMatch, bool PartialOrdering, PackFold PackFold, bool *HasDeducedAnyParam)
static TemplateDeductionResult DeduceTemplateSpecArguments(Sema &S, TemplateParameterList *TemplateParams, const QualType P, QualType A, TemplateDeductionInfo &Info, bool PartialOrdering, SmallVectorImpl< DeducedTemplateArgument > &Deduced, bool *HasDeducedAnyParam)
static TemplateDeductionResult DeduceTemplateArgumentsByTypeMatch(Sema &S, TemplateParameterList *TemplateParams, QualType Param, QualType Arg, TemplateDeductionInfo &Info, SmallVectorImpl< DeducedTemplateArgument > &Deduced, unsigned TDF, PartialOrderingKind POK, bool DeducedFromArrayBound, bool *HasDeducedAnyParam)
Deduce the template arguments by comparing the parameter type and the argument type (C++ [temp....
static TemplateDeductionResult CheckDeductionConsistency(Sema &S, FunctionTemplateDecl *FTD, UnsignedOrNone ArgIdx, QualType P, QualType A, ArrayRef< TemplateArgument > DeducedArgs, bool CheckConsistency)
static PartialOrderingKind degradeCallPartialOrderingKind(PartialOrderingKind POK)
When propagating a partial ordering kind into a NonCall context, this is used to downgrade a 'Call' i...
static MoreSpecializedTrailingPackTieBreakerResult getMoreSpecializedTrailingPackTieBreaker(const TemplateSpecializationType *TST1, const TemplateSpecializationType *TST2)
static TemplateLikeDecl * getMoreSpecialized(Sema &S, QualType T1, QualType T2, TemplateLikeDecl *P1, PrimaryDel *P2, TemplateDeductionInfo &Info)
Returns the more specialized template specialization between T1/P1 and T2/P2.
static DeducedTemplateArgument checkDeducedTemplateArguments(ASTContext &Context, const DeducedTemplateArgument &X, const DeducedTemplateArgument &Y, bool AggregateCandidateDeduction=false)
Verify that the given, deduced template arguments are compatible.
static const Expr * unwrapExpressionForDeduction(const Expr *E)
static bool isSameDeclaration(Decl *X, Decl *Y)
Determine whether two declaration pointers refer to the same declaration.
static NonTypeOrVarTemplateParmDecl getDeducedNTTParameterFromExpr(const Expr *E, unsigned Depth)
If the given expression is of a form that permits the deduction of a non-type template parameter,...
static TemplateDeductionResult DeduceForEachType(Sema &S, TemplateParameterList *TemplateParams, ArrayRef< QualType > Params, ArrayRef< QualType > Args, TemplateDeductionInfo &Info, SmallVectorImpl< DeducedTemplateArgument > &Deduced, PartialOrderingKind POK, bool FinishingDeduction, T &&DeductFunc)
static TemplateDeductionResult DeduceTemplateBases(Sema &S, const CXXRecordDecl *RD, TemplateParameterList *TemplateParams, QualType P, TemplateDeductionInfo &Info, bool PartialOrdering, SmallVectorImpl< DeducedTemplateArgument > &Deduced, bool *HasDeducedAnyParam)
Attempt to deduce the template arguments by checking the base types according to (C++20 [temp....
static bool hasTemplateArgumentForDeduction(ArrayRef< TemplateArgument > &Args, unsigned &ArgIdx)
Determine whether there is a template argument to be used for deduction.
static DeclContext * getAsDeclContextOrEnclosing(Decl *D)
static bool hasInconsistentOrSupersetQualifiersOf(QualType ParamType, QualType ArgType)
Determine whether the parameter has qualifiers that the argument lacks.
static void MarkUsedTemplateParameters(ASTContext &Ctx, const TemplateArgument &TemplateArg, bool OnlyDeduced, unsigned Depth, llvm::SmallBitVector &Used)
Mark the template parameters that are used by this template argument.
static UnsignedOrNone getPackIndexForParam(Sema &S, FunctionTemplateDecl *FunctionTemplate, const MultiLevelTemplateArgumentList &Args, unsigned ParamIdx)
Find the pack index for a particular parameter index in an instantiation of a function template with ...
static QualType GetTypeOfFunction(Sema &S, const OverloadExpr::FindResult &R, FunctionDecl *Fn)
Gets the type of a function for template-argument-deducton purposes when it's considered as part of a...
static bool hasPackExpansionBeforeEnd(ArrayRef< TemplateArgument > Args)
Determine whether the given set of template arguments has a pack expansion that is not the last templ...
static bool isSimpleTemplateIdType(QualType T)
Determine whether the given type T is a simple-template-id type.
PartialOrderingKind
The kind of PartialOrdering we're performing template argument deduction for (C++11 [temp....
MoreSpecializedTrailingPackTieBreakerResult
static TemplateParameter makeTemplateParameter(Decl *D)
Helper function to build a TemplateParameter when we don't know its type statically.
static TemplateDeductionResult CheckOriginalCallArgDeduction(Sema &S, TemplateDeductionInfo &Info, Sema::OriginalCallArg OriginalArg, QualType DeducedA)
Check whether the deduced argument type for a call to a function template matches the actual argument...
static bool AdjustFunctionParmAndArgTypesForDeduction(Sema &S, TemplateParameterList *TemplateParams, unsigned FirstInnerIndex, QualType &ParamType, QualType &ArgType, Expr::Classification ArgClassification, Expr *Arg, unsigned &TDF, TemplateSpecCandidateSet *FailedTSC=nullptr)
Perform the adjustments to the parameter and argument types described in C++ [temp....
static TemplateDeductionResult DeduceTemplateArgumentsFromCallArgument(Sema &S, TemplateParameterList *TemplateParams, unsigned FirstInnerIndex, QualType ParamType, QualType ArgType, Expr::Classification ArgClassification, Expr *Arg, TemplateDeductionInfo &Info, SmallVectorImpl< DeducedTemplateArgument > &Deduced, SmallVectorImpl< Sema::OriginalCallArg > &OriginalCallArgs, bool DecomposedParam, unsigned ArgIdx, unsigned TDF, TemplateSpecCandidateSet *FailedTSC=nullptr)
Perform template argument deduction per [temp.deduct.call] for a single parameter / argument pair.
static bool isAtLeastAsSpecializedAs(Sema &S, SourceLocation Loc, FunctionTemplateDecl *FT1, FunctionTemplateDecl *FT2, TemplatePartialOrderingContext TPOC, ArrayRef< QualType > Args1, ArrayRef< QualType > Args2, bool Args1Offset)
Determine whether the function template FT1 is at least as specialized as FT2.
static QualType GetImplicitObjectParameterType(ASTContext &Context, const CXXMethodDecl *Method, QualType RawType, bool IsOtherRvr)
static TemplateDeductionResult DeduceFromInitializerList(Sema &S, TemplateParameterList *TemplateParams, QualType AdjustedParamType, InitListExpr *ILE, TemplateDeductionInfo &Info, SmallVectorImpl< DeducedTemplateArgument > &Deduced, SmallVectorImpl< Sema::OriginalCallArg > &OriginalCallArgs, unsigned ArgIdx, unsigned TDF)
Attempt template argument deduction from an initializer list deemed to be an argument in a function c...
static unsigned getFirstInnerIndex(FunctionTemplateDecl *FTD)
Get the index of the first template parameter that was originally from the innermost template-paramet...
PackFold
What directions packs are allowed to match non-packs.
static TemplateDeductionResult ConvertDeducedTemplateArguments(Sema &S, NamedDecl *Template, TemplateParameterList *TemplateParams, bool IsDeduced, SmallVectorImpl< DeducedTemplateArgument > &Deduced, TemplateDeductionInfo &Info, Sema::CheckTemplateArgumentInfo &CTAI, LocalInstantiationScope *CurrentInstantiationScope, unsigned NumAlreadyConverted, bool *IsIncomplete)
static QualType ResolveOverloadForDeduction(Sema &S, TemplateParameterList *TemplateParams, Expr *Arg, QualType ParamType, bool ParamWasReference, TemplateSpecCandidateSet *FailedTSC=nullptr)
Apply the deduction rules for overload sets.
static bool IsPossiblyOpaquelyQualifiedType(QualType T)
Determines whether the given type is an opaque type that might be more qualified when instantiated.
static TemplateDeductionResult CheckDeducedArgumentConstraints(Sema &S, NamedDecl *Template, ArrayRef< TemplateArgument > SugaredDeducedArgs, ArrayRef< TemplateArgument > CanonicalDeducedArgs, TemplateDeductionInfo &Info)
static const TemplateSpecializationType * getLastTemplateSpecType(QualType QT)
Deduce the template arguments by comparing the template parameter type (which is a template-id) with ...
static TemplateDeductionResult instantiateExplicitSpecifierDeferred(Sema &S, FunctionDecl *Specialization, const MultiLevelTemplateArgumentList &SubstArgs, TemplateDeductionInfo &Info, FunctionTemplateDecl *FunctionTemplate, ArrayRef< TemplateArgument > DeducedArgs)
static bool CheckDeducedPlaceholderConstraints(Sema &S, const AutoType &Type, AutoTypeLoc TypeLoc, QualType Deduced)
static TemplateDeductionResult DeduceNonTypeTemplateArgument(Sema &S, TemplateParameterList *TemplateParams, const NonTypeOrVarTemplateParmDecl NTTP, const DeducedTemplateArgument &NewDeduced, QualType ValueType, TemplateDeductionInfo &Info, bool PartialOrdering, SmallVectorImpl< DeducedTemplateArgument > &Deduced, bool *HasDeducedAnyParam)
Deduce the value of the given non-type template parameter as the given deduced template argument.
static bool IsPossiblyOpaquelyQualifiedTypeInternal(const Type *T)
static bool hasDeducibleTemplateParameters(Sema &S, FunctionTemplateDecl *FunctionTemplate, QualType T)
static bool isForwardingReference(QualType Param, unsigned FirstInnerIndex)
Determine whether a type denotes a forwarding reference.
static TemplateDeductionResult FinishTemplateArgumentDeduction(Sema &S, NamedDecl *Entity, TemplateParameterList *EntityTPL, TemplateDecl *Template, bool PartialOrdering, ArrayRef< TemplateArgumentLoc > Ps, ArrayRef< TemplateArgument > As, SmallVectorImpl< DeducedTemplateArgument > &Deduced, TemplateDeductionInfo &Info, bool CopyDeducedArgs)
Complete template argument deduction.
static bool isParameterPack(Expr *PackExpression)
Defines the clang::SourceLocation class and associated facilities.
Defines various enumerations that describe declaration and type specifiers.
static QualType getPointeeType(const MemRegion *R)
Defines the clang::TemplateNameKind enum.
Defines the clang::TypeLoc interface and its subclasses.
Allows QualTypes to be sorted and hence used in maps and sets.
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 getBlockPointerType(QualType T) const
Return the uniqued reference to the type for a block of the specified type.
TemplateArgument getCanonicalTemplateArgument(const TemplateArgument &Arg) const
Retrieve the "canonical" template argument.
CanQualType getCanonicalType(QualType T) const
Return the canonical (structural) type corresponding to the specified potentially non-canonical type ...
bool hasSameType(QualType T1, QualType T2) const
Determine whether the given types T1 and T2 are equivalent.
QualType getCanonicalTemplateSpecializationType(TemplateName T, ArrayRef< TemplateArgument > CanonicalArgs) const
QualType getPointerType(QualType T) const
Return the uniqued reference to the type for a pointer to the specified type.
const IncompleteArrayType * getAsIncompleteArrayType(QualType T) const
bool hasSameFunctionTypeIgnoringExceptionSpec(QualType T, QualType U) const
Determine whether two function types are the same, ignoring exception specifications in cases where t...
QualType getLValueReferenceType(QualType T, bool SpelledAsLValue=true) const
Return the uniqued reference to the type for an lvalue reference to the specified type.
const LangOptions & getLangOpts() const
QualType getDecayedType(QualType T) const
Return the uniqued reference to the decayed version of the given type.
QualType getFunctionTypeWithExceptionSpec(QualType Orig, const FunctionProtoType::ExceptionSpecInfo &ESI) const
Get a function type and produce the equivalent function type with the specified exception specificati...
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.
bool hasSameUnqualifiedType(QualType T1, QualType T2) const
Determine whether the given types are equivalent after cvr-qualifiers have been removed.
TemplateArgument getInjectedTemplateArg(NamedDecl *ParamDecl) const
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 getArrayDecayedType(QualType T) const
Return the properly qualified result of decaying the specified array type to a pointer.
QualType getFunctionType(QualType ResultTy, ArrayRef< QualType > Args, const FunctionProtoType::ExtProtoInfo &EPI) const
Return a normal function type with a typed argument list.
QualType 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 ...
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 ...
QualType getUnconstrainedType(QualType T) const
Remove any type constraints from a template parameter type, for equivalence comparison of template pa...
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.
void adjustDeducedFunctionResultType(FunctionDecl *FD, QualType ResultType)
Change the result type of a function type once it is deduced.
bool canonicalizeTemplateArguments(MutableArrayRef< TemplateArgument > Args) const
Canonicalize the given template argument list.
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 getCommonSugaredType(QualType X, QualType Y, bool Unqualified=false) const
const DependentSizedArrayType * getAsDependentSizedArrayType(QualType T) const
The result of parsing/analyzing an expression, statement etc.
Represents a C++11 auto or C++14 decltype(auto) type, possibly constrained by a type-constraint.
ArrayRef< TemplateArgument > getTypeConstraintArguments() const
bool isDecltypeAuto() const
AutoTypeKeyword getKeyword() const
bool isConstrained() const
TemplateDecl * getTypeConstraintConcept() const
A fixed int type of a specified bitwidth.
Represents a C++ conversion function within a class.
QualType getConversionType() const
Returns the type that this conversion function is converting to.
Represents a static or instance method of a struct/union/class.
bool isExplicitObjectMemberFunction() const
[C++2b][dcl.fct]/p7 An explicit object member function is a non-static member function with an explic...
RefQualifierKind getRefQualifier() const
Retrieve the ref-qualifier associated with this method.
The null pointer literal (C++11 [lex.nullptr])
Represents a C++ struct/union/class.
CXXMethodDecl * getLambdaCallOperator() const
Retrieve the lambda call operator of the closure type if this is a closure type.
Declaration of a class template.
CanQualType getCanonicalInjectedSpecializationType(const ASTContext &Ctx) const
Retrieve the canonical template specialization type of the injected-class-name for this class templat...
CanQualType getCanonicalInjectedSpecializationType(const ASTContext &Ctx) const
Retrieves the canonical injected specialization type for this partial specialization.
ClassTemplateDecl * getSpecializedTemplate() const
Retrieve the template that this specialization specializes.
Complex values, per C99 6.2.5p11.
Declaration of a C++20 concept.
const TypeClass * getTypePtr() const
Represents a concrete matrix type with constant number of rows and columns.
unsigned getNumColumns() const
Returns the number of columns in the matrix.
unsigned getNumRows() const
Returns the number of rows in the matrix.
The result of a constraint satisfaction check, containing the necessary information to diagnose an un...
A POD class for pairing a NamedDecl* with an access specifier.
DeclContext - This is used only as base class of specific decl types that can act as declaration cont...
DeclContext * getParent()
getParent - Returns the containing DeclContext.
A reference to a declared variable, function, enum, etc.
Decl - This represents one declaration (or definition), e.g.
TemplateDecl * getDescribedTemplate() const
If this is a declaration that describes some template, this method returns that template declaration.
ASTContext & getASTContext() const LLVM_READONLY
bool isParameterPack() const
Whether this declaration is a parameter pack.
bool isInvalidDecl() const
SourceLocation getLocation() const
bool isTemplateParameterPack() const
isTemplateParameter - Determines whether this declaration is a template parameter pack.
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
TemplateName getTemplateName() const
Retrieve the name of the template that we are deducing.
Common base class for placeholders for types that get replaced by placeholder type deduction: C++11 a...
Represents an extended address space qualifier where the input address space value is dependent.
Expr * getAddrSpaceExpr() const
QualType getPointeeType() const
Represents an extended vector type where either the type or size is dependent.
Expr * getSizeExpr() const
QualType getElementType() const
Represents a matrix type where the type and the number of rows and columns is dependent on a template...
Expr * getColumnExpr() const
Expr * getRowExpr() const
Represents a template specialization type whose template cannot be resolved, e.g.
const DependentTemplateStorage & getDependentTemplateName() const
ArrayRef< TemplateArgument > template_arguments() const
NestedNameSpecifier getQualifier() const
Return the nested name specifier that qualifies this name.
Represents a vector type where either the type or size is dependent.
Recursive AST visitor that supports extension via dynamic dispatch.
virtual bool TraverseTemplateArgumentLoc(const TemplateArgumentLoc &ArgLoc)
Recursively visit a template argument location and dispatch to the appropriate method for the argumen...
virtual bool TraverseTemplateName(TemplateName Template)
Recursively visit a template name and dispatch to the appropriate method.
RAII object that enters a new expression evaluation context.
Store information needed for an explicit specifier.
bool isInvalid() const
Determine if the explicit specifier is invalid.
const Expr * getExpr() const
The return type of classify().
This represents one expression.
bool isValueDependent() const
Determines whether the value of this expression depends on.
std::optional< llvm::APSInt > getIntegerConstantExpr(const ASTContext &Ctx) const
isIntegerConstantExpr - Return the value if this expression is a valid integer constant expression.
SourceLocation getExprLoc() const LLVM_READONLY
getExprLoc - Return the preferred location for the arrow when diagnosing a problem with a generic exp...
Classification Classify(ASTContext &Ctx) const
Classify - Classify this expression according to the C++11 expression taxonomy.
ExtVectorType - Extended vector type.
Stores a list of template parameters and the associated requires-clause (if any) for a TemplateDecl a...
Represents a function declaration or definition.
const ParmVarDecl * getParamDecl(unsigned i) const
bool isFunctionTemplateSpecialization() const
Determine whether this function is a function template specialization.
FunctionTemplateDecl * getDescribedFunctionTemplate() const
Retrieves the function template that is described by this function declaration.
bool hasCXXExplicitFunctionObjectParameter() const
QualType getReturnType() const
ArrayRef< ParmVarDecl * > parameters() const
FunctionDecl * getTemplateInstantiationPattern(bool ForDefinition=true) const
Retrieve the function declaration from which this function could be instantiated, if it is an instant...
void getAssociatedConstraints(SmallVectorImpl< AssociatedConstraint > &ACs) const
Get the associated-constraints of this function declaration.
const TemplateArgumentList * getTemplateSpecializationArgs() const
Retrieve the template arguments used to produce this function template specialization from the primar...
bool isImmediateEscalating() const
OverloadedOperatorKind getOverloadedOperator() const
getOverloadedOperator - Which C++ overloaded operator this function represents, if any.
size_t param_size() const
Represents a prototype with parameter type info, e.g.
param_type_iterator param_type_begin() const
const ExtParameterInfo * getExtParameterInfosOrNull() const
Return a pointer to the beginning of the array of extra parameter information, if present,...
unsigned getNumParams() const
bool hasTrailingReturn() const
Whether this function prototype has a trailing return type.
Qualifiers getMethodQuals() const
QualType getParamType(unsigned i) const
bool hasExceptionSpec() const
Return whether this function has any kind of exception spec.
bool isVariadic() const
Whether this function prototype is variadic.
ExtProtoInfo getExtProtoInfo() const
Expr * getNoexceptExpr() const
Return the expression inside noexcept(expression), or a null pointer if there is none (because the ex...
param_type_iterator param_type_end() const
ArrayRef< QualType > getParamTypes() const
RefQualifierKind getRefQualifier() const
Retrieve the ref-qualifier associated with this function type.
Declaration of a template function.
FunctionDecl * getTemplatedDecl() const
Get the underlying function declaration of the template.
FunctionType - C99 6.7.5.3 - Function Declarators.
QualType getReturnType() const
static ImplicitConceptSpecializationDecl * Create(const ASTContext &C, DeclContext *DC, SourceLocation SL, ArrayRef< TemplateArgument > ConvertedArgs)
Describes an C or C++ initializer list.
unsigned getNumInits() const
unsigned getNumInitsWithEmbedExpanded() const
getNumInits but if the list has an EmbedExpr inside includes full length of embedded data.
ArrayRef< Expr * > inits()
The injected class name of a C++ class template or class template partial specialization.
ElaboratedTypeKeyword getKeyword() const
An lvalue reference type, per C++11 [dcl.ref].
A C++ lambda expression, which produces a function object (of unspecified type) that can be invoked l...
A stack-allocated class that identifies which local variable declaration instantiations are present i...
void SetPartiallySubstitutedPack(NamedDecl *Pack, const TemplateArgument *ExplicitArgs, unsigned NumExplicitArgs)
Note that the given parameter pack has been partially substituted via explicit specification of templ...
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 replaceInnermostTemplateArguments(Decl *AssociatedDecl, ArgList Args)
Replaces the current 'innermost' level with the provided argument list.
void addOuterRetainedLevels(unsigned Num)
This represents a decl that may have a name.
DeclarationName getDeclName() const
Get the actual, stored name of the declaration, which may be a special name.
Class that aids in the construction of nested-name-specifiers along with source-location information ...
Represents a C++ nested name specifier, such as "\::std::vector<int>::".
const Type * getAsType() const
@ Type
A type, stored as a Type*.
NonTypeTemplateParmDecl - Declares a non-type template parameter, e.g., "Size" in.
Represents a pointer to an Objective C object.
A reference to an overloaded function set, either an UnresolvedLookupExpr or an UnresolvedMemberExpr.
bool isVarDeclReference() const
bool hasExplicitTemplateArgs() const
Determines whether this expression had explicit template arguments.
static FindResult find(Expr *E)
Finds the overloaded expression in the given expression E of OverloadTy.
SourceLocation getNameLoc() const
Gets the location of the name.
decls_iterator decls_begin() const
TemplateTemplateParmDecl * getTemplateTemplateDecl() const
void copyTemplateArgumentsInto(TemplateArgumentListInfo &List) const
Copies the template arguments into the given structure.
bool isConceptReference() const
decls_iterator decls_end() const
ArrayRef< TemplateArgumentLoc > template_arguments() const
Represents a C++11 pack expansion that produces a sequence of expressions.
Represents a pack expansion of types.
UnsignedOrNone getNumExpansions() const
Retrieve the number of expansions that this pack expansion will generate, if known.
QualType getPattern() const
Retrieve the pattern of this pack expansion, which is the type that will be repeatedly instantiated w...
bool hasSelectedType() const
QualType getSelectedType() const
A single parameter index whose accessors require each use to make explicit the parameter index encodi...
PointerType - C99 6.7.5.1 - Pointer Declarators.
QualType getPointeeType() const
A (possibly-)qualified type.
bool hasQualifiers() const
Determine whether this type has any qualifiers.
bool isNull() const
Return true if this QualType doesn't point to a type yet.
const Type * getTypePtr() const
Retrieves a pointer to the underlying (unqualified) type.
LangAS getAddressSpace() const
Return the address space of this type.
Qualifiers getQualifiers() const
Retrieve the set of qualifiers applied to this type.
QualType getNonReferenceType() const
If Type is a reference type (e.g., const int&), returns the type that the reference refers to ("const...
QualType getCanonicalType() const
QualType getUnqualifiedType() const
Retrieve the unqualified variant of the given type, removing as little sugar as possible.
bool hasAddressSpace() const
Check if this type has any address space qualifier.
unsigned getCVRQualifiers() const
Retrieve the set of CVR (const-volatile-restrict) qualifiers applied to this type.
Represents a template name as written in source code.
The collection of all-type qualifiers we support.
unsigned getCVRQualifiers() const
void removeCVRQualifiers(unsigned mask)
@ OCL_Strong
Assigning into this object requires the old value to be released and the new value to be retained.
@ OCL_ExplicitNone
This object can be modified without requiring retains or releases.
@ OCL_None
There is no lifetime qualification on this type.
void removeObjCLifetime()
bool isStrictSupersetOf(Qualifiers Other) const
Determine whether this set of qualifiers is a strict superset of another set of qualifiers,...
bool hasNonTrivialObjCLifetime() const
True if the lifetime is neither None or ExplicitNone.
bool 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, bool DeferHint=false)
Emit a diagnostic.
RAII object used to change the argument pack substitution index within a Sema object.
RAII object used to temporarily allow the C++ 'this' expression to be used, with the given qualifiers...
A helper class for building up ExtParameterInfos.
const FunctionProtoType::ExtParameterInfo * getPointerOrNull(unsigned numParams)
Return a pointer (suitable for setting in an ExtProtoInfo) to the ExtParameterInfo array we've built ...
RAII class used to determine whether SFINAE has trapped any errors that occur during template argumen...
bool hasErrorOccurred() const
Determine whether any SFINAE errors have been trapped.
Sema - This implements semantic analysis and AST building for C.
bool TryFunctionConversion(QualType FromType, QualType ToType, QualType &ResultTy) const
Same as IsFunctionConversion, but if this would return true, it sets ResultTy to ToType.
QualType SubstAutoType(QualType TypeWithAuto, QualType Replacement)
Substitute Replacement for auto in TypeWithAuto.
LocalInstantiationScope * CurrentInstantiationScope
The current instantiation scope used to store local variables.
TemplateArgumentLoc getTrivialTemplateArgumentLoc(const TemplateArgument &Arg, QualType NTTPType, SourceLocation Loc, NamedDecl *TemplateParam=nullptr)
Allocate a TemplateArgumentLoc where all locations have been initialized to the given location.
TemplateDeductionResult DeduceTemplateArgumentsFromType(TemplateDecl *TD, QualType FromType, sema::TemplateDeductionInfo &Info)
Deduce the template arguments of the given template from FromType.
QualType ReplaceAutoType(QualType TypeWithAuto, QualType Replacement)
Completely replace the auto in TypeWithAuto by Replacement.
bool TemplateParameterListsAreEqual(const TemplateCompareNewDeclInfo &NewInstFrom, TemplateParameterList *New, const NamedDecl *OldInstFrom, TemplateParameterList *Old, bool Complain, TemplateParameterListEqualKind Kind, SourceLocation TemplateArgLoc=SourceLocation())
Determine whether the given template parameter lists are equivalent.
ClassTemplatePartialSpecializationDecl * getMoreSpecializedPartialSpecialization(ClassTemplatePartialSpecializationDecl *PS1, ClassTemplatePartialSpecializationDecl *PS2, SourceLocation Loc)
Returns the more specialized class template partial specialization according to the rules of partial ...
const ExpressionEvaluationContextRecord & currentEvaluationContext() const
FunctionDecl * getMoreConstrainedFunction(FunctionDecl *FD1, FunctionDecl *FD2)
Returns the more constrained function according to the rules of partial ordering by constraints (C++ ...
FunctionDecl * InstantiateFunctionDeclaration(FunctionTemplateDecl *FTD, const TemplateArgumentList *Args, SourceLocation Loc, CodeSynthesisContext::SynthesisKind CSC=CodeSynthesisContext::ExplicitTemplateArgumentSubstitution)
Instantiate (or find existing instantiation of) a function template with a given set of template argu...
QualType BuildStdInitializerList(QualType Element, SourceLocation Loc)
Looks for the std::initializer_list template and instantiates it with Element, or emits an error if i...
TemplateDeductionResult FinishTemplateArgumentDeduction(FunctionTemplateDecl *FunctionTemplate, SmallVectorImpl< DeducedTemplateArgument > &Deduced, unsigned NumExplicitlySpecified, FunctionDecl *&Specialization, sema::TemplateDeductionInfo &Info, SmallVectorImpl< OriginalCallArg > const *OriginalCallArgs, bool PartialOverloading, bool PartialOrdering, bool ForOverloadSetAddressResolution, llvm::function_ref< bool(bool)> CheckNonDependent=[](bool) { return false;})
Finish template argument deduction for a function template, checking the deduced template arguments f...
@ CTAK_DeducedFromArrayBound
The template argument was deduced from an array bound via template argument deduction.
@ CTAK_Specified
The template argument was specified in the code or was instantiated with some deduced template argume...
@ CTAK_Deduced
The template argument was deduced via template argument deduction.
bool DeduceReturnType(FunctionDecl *FD, SourceLocation Loc, bool Diagnose=true)
bool IsQualificationConversion(QualType FromType, QualType ToType, bool CStyle, bool &ObjCLifetimeConversion)
IsQualificationConversion - Determines whether the conversion from an rvalue of type FromType to ToTy...
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)
@ 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
bool CheckConstraintSatisfaction(const NamedDecl *Template, ArrayRef< AssociatedConstraint > AssociatedConstraints, const MultiLevelTemplateArgumentList &TemplateArgLists, SourceRange TemplateIDRange, ConstraintSatisfaction &Satisfaction)
Check whether the given list of constraint expressions are satisfied (as if in a 'conjunction') given...
void collectUnexpandedParameterPacks(TemplateArgument Arg, SmallVectorImpl< UnexpandedParameterPack > &Unexpanded)
Collect the set of unexpanded parameter packs within the given template argument.
UnsignedOrNone getNumArgumentsInExpansion(QualType T, const MultiLevelTemplateArgumentList &TemplateArgs)
Determine the number of arguments in the given pack expansion type.
ExplicitSpecifier instantiateExplicitSpecifier(const MultiLevelTemplateArgumentList &TemplateArgs, ExplicitSpecifier ES)
TemplateDeductionResult SubstituteExplicitTemplateArguments(FunctionTemplateDecl *FunctionTemplate, TemplateArgumentListInfo &ExplicitTemplateArgs, SmallVectorImpl< DeducedTemplateArgument > &Deduced, SmallVectorImpl< QualType > &ParamTypes, QualType *FunctionType, sema::TemplateDeductionInfo &Info)
Substitute the explicitly-provided template arguments into the given function template according to C...
bool SubstParmTypes(SourceLocation Loc, ArrayRef< ParmVarDecl * > Params, const FunctionProtoType::ExtParameterInfo *ExtParamInfos, const MultiLevelTemplateArgumentList &TemplateArgs, SmallVectorImpl< QualType > &ParamTypes, SmallVectorImpl< ParmVarDecl * > *OutParams, ExtParameterInfoBuilder &ParamInfos)
Substitute the given template arguments into the given set of parameters, producing the set of parame...
FunctionDecl * resolveAddressOfSingleOverloadCandidate(Expr *E, DeclAccessPair &FoundResult)
Given an expression that refers to an overloaded function, try to resolve that function to a single f...
DeclContext * CurContext
CurContext - This is the current declaration context of parsing.
MultiLevelTemplateArgumentList getTemplateInstantiationArgs(const NamedDecl *D, const DeclContext *DC=nullptr, bool Final=false, std::optional< ArrayRef< TemplateArgument > > Innermost=std::nullopt, bool RelativeToPrimary=false, const FunctionDecl *Pattern=nullptr, bool ForConstraintInstantiation=false, bool SkipForSpecialization=false, bool ForDefaultArgumentSubstitution=false)
Retrieve the template argument list(s) that should be used to instantiate the definition of the given...
SuppressedDiagnosticsMap SuppressedDiagnostics
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.
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.
bool IsFunctionConversion(QualType FromType, QualType ToType, bool *DiscardingCFIUncheckedCallee=nullptr, bool *AddingCFIUncheckedCallee=nullptr) const
Determine whether the conversion from FromType to ToType is a valid conversion that strips "noexcept"...
Decl * SubstDecl(Decl *D, DeclContext *Owner, const MultiLevelTemplateArgumentList &TemplateArgs)
TemplateArgumentLoc SubstDefaultTemplateArgumentIfAvailable(TemplateDecl *Template, SourceLocation TemplateKWLoc, SourceLocation TemplateNameLoc, SourceLocation RAngleLoc, Decl *Param, ArrayRef< TemplateArgument > SugaredConverted, ArrayRef< TemplateArgument > CanonicalConverted, bool &HasDefaultArg)
If the given template parameter has a default template argument, substitute into that default templat...
TypeSourceInfo * SubstAutoTypeSourceInfoDependent(TypeSourceInfo *TypeWithAuto)
TypeSourceInfo * ReplaceAutoTypeSourceInfo(TypeSourceInfo *TypeWithAuto, QualType Replacement)
bool isCompleteType(SourceLocation Loc, QualType T, CompleteTypeKind Kind=CompleteTypeKind::Default)
bool isStdInitializerList(QualType Ty, QualType *Element)
Tests whether Ty is an instance of std::initializer_list and, if it is and Element is not NULL,...
void InstantiateFunctionDefinition(SourceLocation PointOfInstantiation, FunctionDecl *Function, bool Recursive=false, bool DefinitionRequired=false, bool AtEndOfTU=false)
Instantiate the definition of the given function from its template.
void MarkUsedTemplateParameters(const Expr *E, bool OnlyDeduced, unsigned Depth, llvm::SmallBitVector &Used)
Mark which template parameters are used in a given expression.
@ Unevaluated
The current expression and its subexpressions occur within an unevaluated operand (C++11 [expr]p7),...
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)
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 DiagnoseUnsatisfiedConstraint(const ConstraintSatisfaction &Satisfaction, bool First=true)
Emit diagnostics explaining why a constraint expression was deemed unsatisfied.
void adjustMemberFunctionCC(QualType &T, bool HasThisPointer, bool IsCtorOrDtor, SourceLocation Loc)
Adjust the calling convention of a method to be the ABI default if it wasn't specified explicitly.
@ Diagnose
Diagnose issues that are non-constant or that are extensions.
ExprResult BuildExpressionFromDeclTemplateArgument(const TemplateArgument &Arg, QualType ParamType, SourceLocation Loc, NamedDecl *TemplateParam=nullptr)
Given a non-type template argument that refers to a declaration and the type of its corresponding non...
TemplateDeductionResult DeduceAutoType(TypeLoc AutoTypeLoc, Expr *Initializer, QualType &Result, sema::TemplateDeductionInfo &Info, bool DependentDeduction=false, bool IgnoreConstraints=false, TemplateSpecCandidateSet *FailedTSC=nullptr)
Deduce the type for an auto type-specifier (C++11 [dcl.spec.auto]p6)
QualType adjustCCAndNoReturn(QualType ArgFunctionType, QualType FunctionType, bool AdjustExceptionSpec=false)
Adjust the type ArgFunctionType to match the calling convention, noreturn, and optionally the excepti...
void HandleFunctionTypeMismatch(PartialDiagnostic &PDiag, QualType FromType, QualType ToType)
HandleFunctionTypeMismatch - Gives diagnostic information for differeing function types.
FunctionTemplateDecl * getMoreSpecializedTemplate(FunctionTemplateDecl *FT1, FunctionTemplateDecl *FT2, SourceLocation Loc, TemplatePartialOrderingContext TPOC, unsigned NumCallArguments1, QualType RawObj1Ty={}, QualType RawObj2Ty={}, bool Reversed=false, bool PartialOverloading=false)
Returns the more specialized function template according to the rules of function template partial or...
void MarkDeducedTemplateParameters(const FunctionTemplateDecl *FunctionTemplate, llvm::SmallBitVector &Deduced)
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.
TemplateArgument getArgumentPack() const
Represents the result of substituting a set of types for a template type parameter pack.
unsigned getIndex() const
Returns the index of the replaced parameter in the associated declaration.
const TemplateTypeParmDecl * getReplacedParameter() const
Gets the template parameter declaration that was substituted for.
A convenient class for passing around template argument information.
void addArgument(const TemplateArgumentLoc &Loc)
A template argument list.
static TemplateArgumentList * CreateCopy(ASTContext &Context, ArrayRef< TemplateArgument > Args)
Create a new template argument list that copies the given set of template arguments.
unsigned size() const
Retrieve the number of template arguments in this template argument list.
const TemplateArgument & get(unsigned Idx) const
Retrieve the template argument at a given index.
ArrayRef< TemplateArgument > asArray() const
Produce this as an array ref.
Location wrapper for a TemplateArgument.
const TemplateArgument & getArgument() const
Represents a template argument.
QualType getParamTypeForDecl() const
Expr * getAsExpr() const
Retrieve the template argument as an expression.
pack_iterator pack_end() const
Iterator referencing one past the last argument of a template argument pack.
pack_iterator pack_begin() const
Iterator referencing the first argument of a template argument pack.
QualType getNonTypeTemplateArgumentType() const
If this is a non-type template argument, get its type.
void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Context) const
Used to insert TemplateArguments into FoldingSets.
QualType getAsType() const
Retrieve the type for a type template argument.
llvm::APSInt getAsIntegral() const
Retrieve the template argument as an integral value.
QualType getNullPtrType() const
Retrieve the type for null non-type template argument.
static TemplateArgument CreatePackCopy(ASTContext &Context, ArrayRef< TemplateArgument > Args)
Create a new template argument pack by copying the given set of template arguments.
TemplateName getAsTemplate() const
Retrieve the template name for a template name argument.
TemplateArgument getPackExpansionPattern() const
When the template argument is a pack expansion, returns the pattern of the pack expansion.
bool isNull() const
Determine whether this template argument has no value.
static TemplateArgument getEmptyPack()
unsigned pack_size() const
The number of template arguments in the given template argument pack.
bool structurallyEquals(const TemplateArgument &Other) const
Determines whether two template arguments are superficially the same.
ValueDecl * getAsDecl() const
Retrieve the declaration for a declaration non-type template argument.
ArrayRef< TemplateArgument > pack_elements() const
Iterator range referencing all of the elements of a template argument pack.
@ Declaration
The template argument is a declaration that was provided for a pointer, reference,...
@ Template
The template argument is a template name that was provided for a template template parameter.
@ StructuralValue
The template argument is a non-type template argument that can't be represented by the special-case D...
@ Pack
The template argument is actually a parameter pack.
@ TemplateExpansion
The template argument is a pack expansion of a template name that was provided for a template templat...
@ NullPtr
The template argument is a null pointer or null pointer to member that was provided for a non-type te...
@ Type
The template argument is a type.
@ Null
Represents an empty template argument, e.g., one that has not been deduced.
@ Integral
The template argument is an integral value stored in an llvm::APSInt that was provided for an integra...
@ Expression
The template argument is an expression, and we've not resolved it to one of the other forms yet,...
ArgKind getKind() const
Return the kind of stored template argument.
bool isPackExpansion() const
Determine whether this template argument is a pack expansion.
TemplateName getAsTemplateOrTemplatePattern() const
Retrieve the template argument as a template name; if the argument is a pack expansion,...
The base class of all kinds of template declarations (e.g., class, function, etc.).
void getAssociatedConstraints(llvm::SmallVectorImpl< AssociatedConstraint > &AC) const
Get the total constraint-expression associated with this template, including constraint-expressions d...
SourceRange getSourceRange() const override LLVM_READONLY
Source range that this declaration covers.
TemplateParameterList * getTemplateParameters() const
Get the list of template parameters.
Represents a C++ template name within the type system.
TemplateDecl * getAsTemplateDecl(bool IgnoreDeduced=false) const
Retrieve the underlying template declaration that this template name refers to, if known.
Stores a list of template parameters for a TemplateDecl and its derived classes.
NamedDecl * getParam(unsigned Idx)
ArrayRef< TemplateArgument > getInjectedTemplateArgs(const ASTContext &Context)
Get the template argument list of the template parameter list.
unsigned getDepth() const
Get the depth of this template parameter list in the set of template parameter lists.
SourceLocation getRAngleLoc() const
SourceLocation getLAngleLoc() const
ArrayRef< NamedDecl * > asArray()
SourceLocation getTemplateLoc() const
TemplateSpecCandidateSet - A set of generalized overload candidates, used in template specializations...
void NoteCandidates(Sema &S, SourceLocation Loc)
NoteCandidates - When no template specialization match is found, prints diagnostic messages containin...
Represents a type template specialization; the template must be a class template, a type alias templa...
ArrayRef< TemplateArgument > template_arguments() const
TemplateName getTemplateName() const
Retrieve the name of the template that we are specializing.
TemplateTemplateParmDecl - Declares a template template parameter, e.g., "T" in.
TemplateNameKind templateParameterKind() const
unsigned getIndex() const
Get the index of the template parameter within its parameter list.
unsigned getDepth() const
Get the nesting depth of the template parameter.
bool isExpandedParameterPack() const
Whether this parameter is a template template parameter pack that has a known list of different templ...
Declaration of a template type parameter.
static TemplateTypeParmDecl * Create(const ASTContext &C, DeclContext *DC, SourceLocation KeyLoc, SourceLocation NameLoc, unsigned D, unsigned P, IdentifierInfo *Id, bool Typename, bool ParameterPack, bool HasTypeConstraint=false, UnsignedOrNone NumExpanded=std::nullopt)
unsigned getDepth() const
Retrieve the depth of the template parameter.
Wrapper for template type parameters.
unsigned getIndex() const
unsigned getDepth() const
const Type * getTypeForDecl() const
TyLocType push(QualType T)
Pushes space for a new TypeLoc of the given type.
void reserve(size_t Requested)
Ensures that this buffer has at least as much capacity as described.
Base wrapper for a particular "section" of type source info.
SourceRange getLocalSourceRange() const
Get the local source range.
unsigned getFullDataSize() const
Returns the size of the type source info data block.
void copy(TypeLoc other)
Copies the other type loc into this one.
A container of type source information.
SourceLocation getNameLoc() const
void setNameLoc(SourceLocation Loc)
The base class of the type hierarchy.
const TemplateSpecializationType * getAsNonAliasTemplateSpecializationType() const
Look through sugar for an instance of TemplateSpecializationType which is not a type alias,...
bool isIncompleteArrayType() const
bool isPlaceholderType() const
Test for a type which does not represent an actual type-system type but is instead used as a placehol...
bool isRValueReferenceType() const
CXXRecordDecl * getAsCXXRecordDecl() const
Retrieves the CXXRecordDecl that this type refers to, either because the type is a RecordType or beca...
bool canDecayToPointerType() const
Determines whether this type can decay to a pointer type.
bool isFunctionPointerType() const
bool isPointerType() const
const T * castAs() const
Member-template castAs<specific type>.
bool isReferenceType() const
QualType getPointeeType() const
If this is a pointer, ObjC object pointer, or block pointer, this returns the respective pointee.
AutoType * getContainedAutoType() const
Get the AutoType whose type will be deduced for a variable with an initializer of this type.
bool isLValueReferenceType() const
bool isDependentType() const
Whether this type is a dependent type, meaning that its definition somehow depends on a template para...
QualType getCanonicalTypeInternal() const
bool isMemberPointerType() const
bool isObjCLifetimeType() const
Returns true if objects of this type have lifetime semantics under ARC.
bool isUndeducedType() const
Determine whether this type is an undeduced type, meaning that it somehow involves a C++11 'auto' typ...
bool isFunctionType() const
bool isObjCObjectPointerType() const
bool isMemberFunctionPointerType() const
const T * castAsCanonical() const
Return this type's canonical type cast to the specified type.
bool isAnyPointerType() const
TypeClass getTypeClass() const
bool isCanonicalUnqualified() const
Determines if this type would be canonical if it had no further qualification.
const T * getAs() const
Member-template getAs<specific type>'.
bool isRecordType() const
A reference to a name which we were able to look up during parsing but could not resolve to a specifi...
The iterator over UnresolvedSets.
Represent the declaration of a variable (in which case it is an lvalue) a function (in which case it ...
Represents a variable declaration or definition.
bool isInitCapture() const
Whether this variable is the implicit variable for a lambda init-capture.
Declaration of a variable template.
VarTemplateDecl * getCanonicalDecl() override
Retrieves the canonical declaration of this template.
const TemplateArgumentList & getTemplateArgs() const
Retrieve the template arguments of the variable template specialization.
VarTemplateDecl * getSpecializedTemplate() const
Retrieve the template that this specialization specializes.
Represents a GCC generic vector type.
Provides information about an attempted template argument deduction, whose success or failure was des...
void setExplicitArgs(TemplateArgumentList *NewDeducedSugared, TemplateArgumentList *NewDeducedCanonical)
Provide an initial template argument list that contains the explicitly-specified arguments.
TemplateArgumentList * takeCanonical()
TemplateArgumentList * takeSugared()
Take ownership of the deduced template argument lists.
SourceLocation getLocation() const
Returns the location at which template argument is occurring.
void clearSFINAEDiagnostic()
Discard any SFINAE diagnostics.
TemplateArgument SecondArg
The second template argument to which the template argument deduction failure refers.
void setStrictPackMatch()
TemplateParameter Param
The template parameter to which a template argument deduction failure refers.
diag_iterator diag_end() const
Returns an iterator at the end of the sequence of suppressed diagnostics.
void reset(TemplateArgumentList *NewDeducedSugared, TemplateArgumentList *NewDeducedCanonical)
Provide a new template argument list that contains the results of template argument deduction.
unsigned getDeducedDepth() const
The depth of template parameters for which deduction is being performed.
diag_iterator diag_begin() const
Returns an iterator at the beginning of the sequence of suppressed diagnostics.
TemplateArgument FirstArg
The first template argument to which the template argument deduction failure refers.
ConstraintSatisfaction AssociatedConstraintsSatisfaction
The constraint satisfaction details resulting from the associated constraints satisfaction tests.
unsigned CallArgIndex
The index of the function argument that caused a deduction failure.
bool hasStrictPackMatch() const
__inline void unsigned int _2
The JSON file list parser is used to communicate input to InstallAPI.
@ OO_None
Not an overloaded operator.
@ Match
This is not an overload because the signature exactly matches an existing declaration.
bool isTargetAddressSpace(LangAS AS)
@ Specialization
We are substituting template parameters for template arguments in order to form a template specializa...
@ RQ_None
No ref-qualifier was provided.
@ RQ_RValue
An rvalue ref-qualifier was provided (&&).
NamedDecl * getAsNamedDecl(TemplateParameter P)
bool isPackProducingBuiltinTemplateName(TemplateName N)
UnsignedOrNone getExpandedPackSize(const NamedDecl *Param)
Check whether the template parameter is a pack expansion, and if so, determine the number of paramete...
unsigned toTargetAddressSpace(LangAS AS)
bool isLambdaCallOperator(const CXXMethodDecl *MD)
@ Result
The result type of a method or function.
std::pair< unsigned, unsigned > getDepthAndIndex(const NamedDecl *ND)
Retrieve the depth and index of a template parameter.
@ Template
We are parsing a template declaration.
@ FunctionTemplate
The name was classified as a function template name.
@ Concept
The name was classified as a concept name.
llvm::PointerUnion< TemplateTypeParmDecl *, NonTypeTemplateParmDecl *, TemplateTemplateParmDecl * > TemplateParameter
Stores a template parameter of any kind.
bool isLambdaConversionOperator(CXXConversionDecl *C)
@ TNK_Var_template
The name refers to a variable template whose specialization produces a variable.
@ TNK_Concept_template
The name refers to a concept.
const FunctionProtoType * T
void printTemplateArgumentList(raw_ostream &OS, ArrayRef< TemplateArgument > Args, const PrintingPolicy &Policy, const TemplateParameterList *TPL=nullptr)
Print a template argument list, including the '<' and '>' enclosing the template arguments.
TPOC
The context in which partial ordering of function templates occurs.
@ TPOC_Conversion
Partial ordering of function templates for a call to a conversion function.
@ TPOC_Other
Partial ordering of function templates in other contexts, e.g., taking the address of a function temp...
@ TPOC_Call
Partial ordering of function templates for a function call.
bool declaresSameEntity(const Decl *D1, const Decl *D2)
Determine whether two declarations declare the same entity.
TemplateDeductionResult
Describes the result of template argument deduction.
@ MiscellaneousDeductionFailure
Deduction failed; that's all we know.
@ NonDependentConversionFailure
Checking non-dependent argument conversions failed.
@ ConstraintsNotSatisfied
The deduced arguments did not satisfy the constraints associated with the template.
@ Underqualified
Template argument deduction failed due to inconsistent cv-qualifiers on a template parameter type tha...
@ InstantiationDepth
Template argument deduction exceeded the maximum template instantiation depth (which has already been...
@ InvalidExplicitArguments
The explicitly-specified template arguments were not valid template arguments for the given template.
@ 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.
@ None
The alignment was not explicit in code.
@ Noexcept
Condition in a noexcept(bool) specifier.
@ EST_Uninstantiated
not instantiated yet
@ EST_None
no exception specification
TemplateDeductionFlags
Various flags that control template argument deduction.
@ TDF_None
No template argument deduction flags, which indicates the strictest results for template argument ded...
@ TDF_DerivedClass
Within template argument deduction from a function call, we are matching in a case where we can perfo...
@ TDF_TopLevelParameterTypeList
Whether we are performing template argument deduction for parameters and arguments in a top-level tem...
@ TDF_IgnoreQualifiers
Within template argument deduction from a function call, we are matching in a case where we ignore cv...
@ TDF_ParamWithReferenceType
Within template argument deduction from a function call, we are matching with a parameter type for wh...
@ TDF_SkipNonDependent
Allow non-dependent types to differ, e.g., when performing template argument deduction from a functio...
@ TDF_AllowCompatibleFunctionType
Within template argument deduction from overload resolution per C++ [over.over] allow matching functi...
@ TDF_ArgWithReferenceType
Within template argument deduction for a conversion function, we are matching with an argument type f...
ActionResult< CXXBaseSpecifier * > BaseResult
A pack that we're currently deducing.
DeducedPack(unsigned Index)
SmallVector< DeducedTemplateArgument, 4 > New
DeducedTemplateArgument Saved
DeducedTemplateArgument DeferredDeduction
Holds information about the various types of exception specification.
ExceptionSpecificationType Type
The kind of exception specification this is.
Extra information about a function prototype.
const ExtParameterInfo * ExtParameterInfos
FunctionType::ExtInfo ExtInfo
bool HasFormOfMemberPointer
OverloadExpr * Expression
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 ...
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.