45#include "llvm/ADT/APInt.h"
46#include "llvm/ADT/APSInt.h"
47#include "llvm/ADT/ArrayRef.h"
48#include "llvm/ADT/DenseMap.h"
49#include "llvm/ADT/FoldingSet.h"
50#include "llvm/ADT/SmallBitVector.h"
51#include "llvm/ADT/SmallPtrSet.h"
52#include "llvm/ADT/SmallVector.h"
53#include "llvm/Support/Casting.h"
54#include "llvm/Support/Compiler.h"
55#include "llvm/Support/ErrorHandling.h"
56#include "llvm/Support/SaveAndRestore.h"
114using namespace clang;
120 if (Y.getBitWidth() >
X.getBitWidth())
121 X =
X.extend(Y.getBitWidth());
122 else if (Y.getBitWidth() <
X.getBitWidth())
123 Y = Y.extend(
X.getBitWidth());
126 if (
X.isSigned() != Y.isSigned()) {
128 if ((Y.isSigned() && Y.isNegative()) || (
X.isSigned() &&
X.isNegative()))
147 bool *HasDeducedAnyParam);
163 bool OnlyDeduced,
unsigned Depth,
164 llvm::SmallBitVector &
Used);
167 bool OnlyDeduced,
unsigned Level,
168 llvm::SmallBitVector &Deduced);
178 if (
const auto *IC = dyn_cast<ImplicitCastExpr>(
E))
179 E = IC->getSubExpr();
180 else if (
const auto *CE = dyn_cast<ConstantExpr>(
E))
181 E = CE->getSubExpr();
182 else if (
const auto *Subst = dyn_cast<SubstNonTypeTemplateParmExpr>(
E))
183 E = Subst->getReplacement();
184 else if (
const auto *CCE = dyn_cast<CXXConstructExpr>(
E)) {
186 if (CCE->getParenOrBraceRange().isValid())
189 assert(CCE->getNumArgs() >= 1 &&
"implicit construct expr should have 1 arg");
195 if (
const auto *DRE = dyn_cast<DeclRefExpr>(
E))
196 if (
const auto *NTTP = dyn_cast<NonTypeTemplateParmDecl>(DRE->getDecl()))
197 if (NTTP->getDepth() == Depth)
212 X = NX->getUnderlyingDecl();
213 if (
NamedDecl *NY = dyn_cast<NamedDecl>(Y))
214 Y = NY->getUnderlyingDecl();
227 bool AggregateCandidateDeduction =
false) {
240 QualType XType =
X.getNonTypeTemplateArgumentType();
248 switch (
X.getKind()) {
250 llvm_unreachable(
"Non-deduced template arguments handled above");
257 X.wasDeducedFromArrayBound() ||
263 return X.wasDeducedFromArrayBound() ? Y :
X;
277 return X.wasDeducedFromArrayBound() ? Y :
X;
286 X.structurallyEquals(Y)))
314 llvm::FoldingSetNodeID ID1, ID2;
315 X.getAsExpr()->Profile(ID1, Context,
true);
318 return X.wasDeducedFromArrayBound() ? Y :
X;
325 assert(!
X.wasDeducedFromArrayBound());
338 X.getParamTypeForDecl());
375 (!AggregateCandidateDeduction &&
X.pack_size() != Y.
pack_size()))
387 if (Merged.isNull() && !(XA->isNull() && YA->isNull()))
389 NewPack.push_back(Merged);
392 NewPack.push_back(*XA);
402 llvm_unreachable(
"Invalid TemplateArgument Kind!");
415 bool *HasDeducedAnyParam) {
417 "deducing non-type template argument with wrong depth");
421 if (Result.isNull()) {
425 return TemplateDeductionResult::Inconsistent;
430 return TemplateDeductionResult::Success;
437 return TemplateDeductionResult::Success;
442 if (
auto *Expansion = dyn_cast<PackExpansionType>(ParamType))
443 ParamType = Expansion->getPattern();
457 S, TemplateParams, ParamType, ValueType, Info, Deduced,
471 bool *HasDeducedAnyParam) {
473 S, TemplateParams, NTTP,
475 DeducedFromArrayBound),
487 bool *HasDeducedAnyParam) {
509 bool *HasDeducedAnyParam) {
525 bool *HasDeducedAnyParam) {
537 bool *HasDeducedAnyParam) {
542 return TemplateDeductionResult::Success;
545 if (
auto *TempParam = dyn_cast<TemplateTemplateParmDecl>(ParamDecl)) {
548 return TemplateDeductionResult::Success;
552 unsigned StartPos = 0;
569 Arg, {StartPos, DefaultArguments.drop_front(StartPos)}))
573 S.
Context, Deduced[TempParam->getIndex()], NewDeduced);
574 if (Result.isNull()) {
575 Info.
Param = TempParam;
576 Info.
FirstArg = Deduced[TempParam->getIndex()];
578 return TemplateDeductionResult::Inconsistent;
581 Deduced[TempParam->getIndex()] = Result;
582 if (HasDeducedAnyParam)
583 *HasDeducedAnyParam =
true;
584 return TemplateDeductionResult::Success;
590 return TemplateDeductionResult::Success;
595 return TemplateDeductionResult::NonDeducedMismatch;
621 assert(TST &&
"Expected a TemplateSpecializationType");
633 bool *HasDeducedAnyParam) {
636 UP = IP->getInjectedSpecializationType();
644 return TemplateDeductionResult::Success;
651 ->template_arguments();
654 std::optional<NestedNameSpecifier *> NNS;
657 NNS = Elaborated->getQualifier();
659 UA = Injected->getInjectedSpecializationType();
670 return TemplateDeductionResult::Success;
677 ->template_arguments();
684 Result != TemplateDeductionResult::Success)
691 S, TemplateParams, PResolved, AResolved, Info, Deduced,
701 RA ? dyn_cast<ClassTemplateSpecializationDecl>(RA->getDecl()) :
nullptr;
705 return TemplateDeductionResult::NonDeducedMismatch;
711 *NNS,
false,
TemplateName(SA->getSpecializedTemplate()));
715 S, TemplateParams, TNP, TNA, Info,
717 Deduced, HasDeducedAnyParam);
718 Result != TemplateDeductionResult::Success)
723 SA->getTemplateArgs().asArray(), Info, Deduced,
733 case Type::TypeOfExpr:
735 case Type::DependentName:
737 case Type::PackIndexing:
738 case Type::UnresolvedUsing:
739 case Type::TemplateTypeParm:
743 case Type::ConstantArray:
744 case Type::IncompleteArray:
745 case Type::VariableArray:
746 case Type::DependentSizedArray:
748 cast<ArrayType>(
T)->getElementType().getTypePtr());
797class PackDeductionScope {
805 bool DeducePackIfNotAlreadyDeduced =
false,
806 bool FinishingDeduction =
false)
807 : S(S), TemplateParams(TemplateParams), Deduced(Deduced), Info(Info),
808 DeducePackIfNotAlreadyDeduced(DeducePackIfNotAlreadyDeduced),
809 FinishingDeduction(FinishingDeduction) {
810 unsigned NumNamedPacks = addPacks(Pattern);
811 finishConstruction(NumNamedPacks);
818 : S(S), TemplateParams(TemplateParams), Deduced(Deduced), Info(Info) {
820 finishConstruction(1);
824 void addPack(
unsigned Index) {
827 DeducedFromEarlierParameter = !Deduced[Index].isNull();
829 if (!FinishingDeduction) {
830 Pack.Saved = Deduced[Index];
837 if (std::optional<unsigned> ExpandedPackExpansions =
839 FixedNumExpansions = ExpandedPackExpansions;
841 Packs.push_back(Pack);
847 llvm::SmallBitVector SawIndices(TemplateParams->size());
850 auto AddPack = [&](
unsigned Index) {
851 if (SawIndices[Index])
853 SawIndices[Index] =
true;
860 if (
auto *NTTP = dyn_cast<NonTypeTemplateParmDecl>(
861 TemplateParams->getParam(Index))) {
862 if (!NTTP->isExpandedParameterPack())
865 if (
auto *Expansion = dyn_cast<PackExpansionType>(
867 ExtraDeductions.push_back(Expansion->getPattern());
876 for (
unsigned I = 0, N = Unexpanded.size(); I != N; ++I) {
877 unsigned Depth, Index;
879 if (Depth == Info.getDeducedDepth())
886 assert(!Packs.empty() &&
"Pack expansion without unexpanded packs?");
888 unsigned NumNamedPacks = Packs.size();
892 while (!ExtraDeductions.empty())
893 Collect(ExtraDeductions.pop_back_val());
895 return NumNamedPacks;
898 void finishConstruction(
unsigned NumNamedPacks) {
901 unsigned NumPartialPackArgs = 0;
902 std::pair<unsigned, unsigned> PartialPackDepthIndex(-1u, -1u);
904 if (
auto *Partial =
Scope->getPartiallySubstitutedPack(
905 &PartialPackArgs, &NumPartialPackArgs))
911 bool IsExpanded =
true;
912 for (
unsigned I = 0; I != NumNamedPacks; ++I) {
913 if (Packs[I].Index >= Info.getNumExplicitArgs()) {
915 IsPartiallyExpanded =
false;
918 if (PartialPackDepthIndex ==
919 std::make_pair(Info.getDeducedDepth(), Packs[I].Index)) {
920 IsPartiallyExpanded =
true;
928 if (IsPartiallyExpanded)
929 PackElements += NumPartialPackArgs;
930 else if (IsExpanded && FixedNumExpansions)
931 PackElements += *FixedNumExpansions;
933 for (
auto &Pack : Packs) {
934 if (Info.PendingDeducedPacks.size() > Pack.Index)
935 Pack.Outer = Info.PendingDeducedPacks[Pack.Index];
937 Info.PendingDeducedPacks.resize(Pack.Index + 1);
938 Info.PendingDeducedPacks[Pack.Index] = &Pack;
940 if (PartialPackDepthIndex ==
941 std::make_pair(Info.getDeducedDepth(), Pack.Index)) {
942 Pack.New.append(PartialPackArgs, PartialPackArgs + NumPartialPackArgs);
951 if (!FinishingDeduction && !IsPartiallyExpanded)
952 Deduced[Pack.Index] = Pack.New[PackElements];
958 ~PackDeductionScope() {
959 for (
auto &Pack : Packs)
960 Info.PendingDeducedPacks[Pack.Index] = Pack.Outer;
964 std::optional<unsigned> getSavedPackSizeIfAllEqual()
const {
965 unsigned PackSize = Packs[0].Saved.pack_size();
967 if (std::all_of(Packs.begin() + 1, Packs.end(), [&PackSize](
const auto &
P) {
968 return P.Saved.pack_size() == PackSize;
976 bool isDeducedFromEarlierParameter()
const {
977 return DeducedFromEarlierParameter;
982 bool isPartiallyExpanded() {
return IsPartiallyExpanded; }
987 bool hasFixedArity() {
return FixedNumExpansions.has_value(); }
992 bool hasNextElement() {
993 return !FixedNumExpansions || *FixedNumExpansions > PackElements;
997 void nextPackElement() {
1001 if (!FinishingDeduction) {
1002 for (
auto &Pack : Packs) {
1004 if (!Pack.New.empty() || !DeducedArg.
isNull()) {
1005 while (Pack.New.size() < PackElements)
1007 if (Pack.New.size() == PackElements)
1008 Pack.New.push_back(DeducedArg);
1010 Pack.New[PackElements] = DeducedArg;
1011 DeducedArg = Pack.New.size() > PackElements + 1
1012 ? Pack.New[PackElements + 1]
1024 if (FinishingDeduction)
1025 return TemplateDeductionResult::Success;
1028 for (
auto &Pack : Packs) {
1030 if (!FinishingDeduction)
1031 Deduced[Pack.Index] = Pack.Saved;
1046 Pack.New.resize(PackElements);
1050 if (Pack.New.empty()) {
1056 std::copy(Pack.New.begin(), Pack.New.end(), ArgumentPack);
1064 Pack.New[0].wasDeducedFromArrayBound());
1070 if (Pack.Outer->DeferredDeduction.isNull()) {
1073 Pack.Outer->DeferredDeduction = NewPack;
1076 Loc = &Pack.Outer->DeferredDeduction;
1078 Loc = &Deduced[Pack.Index];
1084 S.
Context, OldPack, NewPack, DeducePackIfNotAlreadyDeduced);
1086 Info.AggregateDeductionCandidateHasMismatchedArity =
1092 if (!Result.isNull() && !Pack.DeferredDeduction.isNull()) {
1094 NewPack = Pack.DeferredDeduction;
1098 NamedDecl *Param = TemplateParams->getParam(Pack.Index);
1099 if (Result.isNull()) {
1101 Info.FirstArg = OldPack;
1102 Info.SecondArg = NewPack;
1103 return TemplateDeductionResult::Inconsistent;
1109 if (*Expansions != PackElements) {
1111 Info.FirstArg = Result;
1112 return TemplateDeductionResult::IncompletePack;
1119 return TemplateDeductionResult::Success;
1127 unsigned PackElements = 0;
1128 bool IsPartiallyExpanded =
false;
1129 bool DeducePackIfNotAlreadyDeduced =
false;
1130 bool DeducedFromEarlierParameter =
false;
1131 bool FinishingDeduction =
false;
1133 std::optional<unsigned> FixedNumExpansions;
1145 bool FinishingDeduction,
T &&DeductFunc) {
1155 = dyn_cast<PackExpansionType>(Params[
ParamIdx]);
1160 if (ArgIdx >= Args.size())
1161 return TemplateDeductionResult::MiscellaneousDeductionFailure;
1163 if (isa<PackExpansionType>(Args[ArgIdx])) {
1168 return TemplateDeductionResult::MiscellaneousDeductionFailure;
1172 DeductFunc(S, TemplateParams,
ParamIdx, ArgIdx,
1173 Params[
ParamIdx].getUnqualifiedType(),
1174 Args[ArgIdx].getUnqualifiedType(), Info, Deduced, POK);
1175 Result != TemplateDeductionResult::Success)
1190 PackDeductionScope PackScope(S, TemplateParams, Deduced, Info, Pattern,
1192 FinishingDeduction);
1196 if (
ParamIdx + 1 == Params.size() || PackScope.hasFixedArity()) {
1197 for (; ArgIdx < Args.size() && PackScope.hasNextElement(); ++ArgIdx) {
1200 S, TemplateParams,
ParamIdx, ArgIdx,
1202 Info, Deduced, POK);
1203 Result != TemplateDeductionResult::Success)
1205 PackScope.nextPackElement();
1226 if (NumExpansions && !PackScope.isPartiallyExpanded()) {
1227 for (
unsigned I = 0; I != *NumExpansions && ArgIdx < Args.size();
1229 PackScope.nextPackElement();
1235 if (
auto Result = PackScope.finish();
1236 Result != TemplateDeductionResult::Success)
1247 isa<PackExpansionType>(Args[ArgIdx]))
1248 return TemplateDeductionResult::Success;
1251 if (ArgIdx < Args.size())
1252 return TemplateDeductionResult::MiscellaneousDeductionFailure;
1254 return TemplateDeductionResult::Success;
1294 llvm::SmallBitVector *HasDeducedParam) {
1295 return ::DeduceForEachType(
1296 S, TemplateParams, Params, Args, Info, Deduced, POK,
1302 bool HasDeducedAnyParamCopy =
false;
1304 S, TemplateParams,
P, A, Info, Deduced, TDF, POK,
1305 false, &HasDeducedAnyParamCopy);
1306 if (HasDeducedAnyParam && HasDeducedAnyParamCopy)
1307 *HasDeducedAnyParam =
true;
1308 if (HasDeducedParam && HasDeducedAnyParamCopy)
1309 (*HasDeducedParam)[
ParamIdx] =
true;
1323 if (ParamQs == ArgQs)
1367 if (!Guide || !Guide->isImplicit())
1369 return Guide->getDeducedTemplate()->getTemplateParameters()->size();
1379 if (ParamRef->getPointeeType().getQualifiers())
1382 return TypeParm && TypeParm->
getIndex() >= FirstInnerIndex;
1410 bool *HasDeducedAnyParam) {
1436 bool HasDeducedAnyParam;
1438 llvm::MapVector<const CXXRecordDecl *, MatchValue> Matches;
1443 assert(
T->
isRecordType() &&
"Base class that isn't a record?");
1445 ToVisit.push_back(
T);
1454 while (!ToVisit.empty()) {
1455 QualType NextT = ToVisit.pop_back_val();
1460 bool HasDeducedAnyParamCopy =
false;
1463 &HasDeducedAnyParamCopy);
1469 Matches.insert({RD, {DeducedCopy, HasDeducedAnyParamCopy}});
1480 if (Matches.size() > 1) {
1482 for (
const auto &Match : Matches)
1483 AddBases(Match.first);
1487 while (Matches.size() > 1 && !ToVisit.empty()) {
1488 const CXXRecordDecl *RD = ToVisit.pop_back_val()->getAsCXXRecordDecl();
1497 if (Matches.empty())
1499 if (Matches.size() > 1)
1502 std::swap(Matches.front().second.Deduced, Deduced);
1503 if (
bool HasDeducedAnyParamCopy = Matches.front().second.HasDeducedAnyParam;
1504 HasDeducedAnyParamCopy && HasDeducedAnyParam)
1505 *HasDeducedAnyParam = HasDeducedAnyParamCopy;
1514 return std::min(POK, PartialOrderingKind::NonCall);
1546 bool *HasDeducedAnyParam) {
1550 if (
const auto *AExp = dyn_cast<PackExpansionType>(A))
1551 A = AExp->getPattern();
1554 if (POK == PartialOrderingKind::Call) {
1632 TDF &= ~TDF_TopLevelParameterTypeList;
1635 P =
P->getPointeeType();
1652 unsigned Index = TTP->getIndex();
1667 Info.
Param = cast<TemplateTypeParmDecl>(TemplateParams->
getParam(Index));
1679 "saw template type parameter with wrong depth");
1681 "Unresolved overloaded function");
1701 Info.
Param = cast<TemplateTypeParmDecl>(TemplateParams->
getParam(Index));
1724 case Decl::TemplateTypeParm:
1725 Info.
Param = cast<TemplateTypeParmDecl>(Param);
1727 case Decl::NonTypeTemplateParm:
1728 Info.
Param = cast<NonTypeTemplateParmDecl>(Param);
1730 case Decl::TemplateTemplateParm:
1731 Info.
Param = cast<TemplateTemplateParmDecl>(Param);
1734 llvm_unreachable(
"unexpected kind");
1742 if (HasDeducedAnyParam)
1743 *HasDeducedAnyParam =
true;
1783 if (!
P->isDependentType()) {
1799 switch (
P.getCanonicalType()->getTypeClass()) {
1801#define NON_CANONICAL_TYPE(Class, Base) \
1802 case Type::Class: llvm_unreachable("deducing non-canonical type: " #Class);
1803#define TYPE(Class, Base)
1804#include "clang/AST/TypeNodes.inc"
1806 case Type::TemplateTypeParm:
1807 case Type::SubstTemplateTypeParmPack:
1808 llvm_unreachable(
"Type nodes handled above");
1816 if (
P->isDependentType())
1820 case Type::VariableArray:
1822 case Type::FunctionNoProto:
1825 case Type::ObjCObject:
1826 case Type::ObjCInterface:
1827 case Type::ObjCObjectPointer:
1837 case Type::Complex: {
1842 S, TemplateParams, CP->getElementType(), CA->getElementType(), Info,
1844 false, HasDeducedAnyParam);
1848 case Type::Atomic: {
1853 S, TemplateParams, PA->getValueType(), AA->getValueType(), Info,
1855 false, HasDeducedAnyParam);
1859 case Type::Pointer: {
1870 PointeeType, Info, Deduced,
1873 false, HasDeducedAnyParam);
1877 case Type::LValueReference: {
1884 S, TemplateParams, RP->getPointeeType(), RA->getPointeeType(), Info,
1886 false, HasDeducedAnyParam);
1890 case Type::RValueReference: {
1897 S, TemplateParams, RP->getPointeeType(), RA->getPointeeType(), Info,
1899 false, HasDeducedAnyParam);
1903 case Type::IncompleteArray: {
1909 assert(IAP &&
"Template parameter not of incomplete array type");
1912 S, TemplateParams, IAP->getElementType(), IAA->getElementType(), Info,
1915 false, HasDeducedAnyParam);
1919 case Type::ConstantArray: {
1923 if (!CAA || CAA->getSize() != CAP->getSize())
1927 S, TemplateParams, CAP->getElementType(), CAA->getElementType(), Info,
1930 false, HasDeducedAnyParam);
1934 case Type::DependentSizedArray: {
1943 S, TemplateParams, DAP->getElementType(), AA->getElementType(),
1946 false, HasDeducedAnyParam);
1959 "saw non-type template parameter with wrong depth");
1960 if (
const auto *CAA = dyn_cast<ConstantArrayType>(AA)) {
1961 llvm::APSInt Size(CAA->getSize());
1964 true, Info, POK != PartialOrderingKind::None,
1965 Deduced, HasDeducedAnyParam);
1967 if (
const auto *DAA = dyn_cast<DependentSizedArrayType>(AA))
1968 if (DAA->getSizeExpr())
1970 S, TemplateParams, NTTP, DAA->getSizeExpr(), Info,
1971 POK != PartialOrderingKind::None, Deduced, HasDeducedAnyParam);
1980 case Type::FunctionProto: {
1986 if (FPP->getMethodQuals() != FPA->getMethodQuals() ||
1987 FPP->getRefQualifier() != FPA->getRefQualifier() ||
1988 FPP->isVariadic() != FPA->isVariadic())
1993 S, TemplateParams, FPP->getReturnType(), FPA->getReturnType(),
1995 false, HasDeducedAnyParam);
2001 S, TemplateParams, FPP->param_types(), FPA->param_types(), Info,
2014 Expr *NoexceptExpr = FPP->getNoexceptExpr();
2019 "saw non-type template parameter with wrong depth");
2021 llvm::APSInt Noexcept(1);
2022 switch (FPA->canThrow()) {
2033 POK != PartialOrderingKind::None, Deduced, HasDeducedAnyParam);
2036 if (
Expr *ArgNoexceptExpr = FPA->getNoexceptExpr())
2038 S, TemplateParams, NTTP, ArgNoexceptExpr, Info,
2039 POK != PartialOrderingKind::None, Deduced, HasDeducedAnyParam);
2052 case Type::InjectedClassName:
2061 case Type::TemplateSpecialization: {
2066 POK != PartialOrderingKind::None,
2067 Deduced, HasDeducedAnyParam);
2073 S, TemplateParams,
P, A, Info, POK != PartialOrderingKind::None,
2074 Deduced, HasDeducedAnyParam);
2089 Deduced = DeducedOrig;
2093 POK != PartialOrderingKind::None,
2094 Deduced, HasDeducedAnyParam);
2108 case Type::MemberPointer: {
2125 S, TemplateParams, PPT, APT, Info, Deduced, SubTDF,
2127 false, HasDeducedAnyParam);
2131 S, TemplateParams,
QualType(MPP->getClass(), 0),
2132 QualType(MPA->getClass(), 0), Info, Deduced, SubTDF,
2134 false, HasDeducedAnyParam);
2142 case Type::BlockPointer: {
2148 S, TemplateParams, BPP->getPointeeType(), BPA->getPointeeType(), Info,
2150 false, HasDeducedAnyParam);
2156 case Type::ExtVector: {
2161 if (VP->getNumElements() != VA->getNumElements())
2163 ElementType = VA->getElementType();
2168 ElementType = VA->getElementType();
2174 S, TemplateParams, VP->getElementType(), ElementType, Info, Deduced,
2176 false, HasDeducedAnyParam);
2179 case Type::DependentVector: {
2185 S, TemplateParams, VP->getElementType(), VA->getElementType(),
2187 false, HasDeducedAnyParam);
2198 ArgSize = VA->getNumElements();
2204 Info, POK != PartialOrderingKind::None, Deduced,
2205 HasDeducedAnyParam);
2211 S, TemplateParams, VP->getElementType(), VA->getElementType(),
2213 false, HasDeducedAnyParam);
2224 S, TemplateParams, NTTP, VA->getSizeExpr(), Info,
2225 POK != PartialOrderingKind::None, Deduced, HasDeducedAnyParam);
2234 case Type::DependentSizedExtVector: {
2240 S, TemplateParams, VP->getElementType(), VA->getElementType(),
2242 false, HasDeducedAnyParam);
2253 ArgSize = VA->getNumElements();
2258 S, TemplateParams, NTTP, ArgSize, S.
Context.
IntTy,
true, Info,
2259 POK != PartialOrderingKind::None, Deduced, HasDeducedAnyParam);
2265 S, TemplateParams, VP->getElementType(), VA->getElementType(),
2267 false, HasDeducedAnyParam);
2278 S, TemplateParams, NTTP, VA->getSizeExpr(), Info,
2279 POK != PartialOrderingKind::None, Deduced, HasDeducedAnyParam);
2289 case Type::ConstantMatrix: {
2296 if (MP->getNumRows() != MA->getNumRows() ||
2297 MP->getNumColumns() != MA->getNumColumns()) {
2302 S, TemplateParams, MP->getElementType(), MA->getElementType(), Info,
2304 false, HasDeducedAnyParam);
2307 case Type::DependentSizedMatrix: {
2317 false, HasDeducedAnyParam);
2322 auto DeduceMatrixArg =
2323 [&S, &Info, &Deduced, &TemplateParams, &HasDeducedAnyParam, POK](
2327 const auto *ACM = dyn_cast<ConstantMatrixType>(A);
2328 const auto *ADM = dyn_cast<DependentSizedMatrixType>(A);
2329 if (!ParamExpr->isValueDependent()) {
2330 std::optional<llvm::APSInt> ParamConst =
2331 ParamExpr->getIntegerConstantExpr(S.
Context);
2336 if ((ACM->*GetArgDimension)() == *ParamConst)
2341 Expr *ArgExpr = (ADM->*GetArgDimensionExpr)();
2342 if (std::optional<llvm::APSInt> ArgConst =
2344 if (*ArgConst == *ParamConst)
2355 llvm::APSInt ArgConst(
2357 ArgConst = (ACM->*GetArgDimension)();
2360 true, Info, POK != PartialOrderingKind::None,
2361 Deduced, HasDeducedAnyParam);
2365 S, TemplateParams, NTTP, (ADM->*GetArgDimensionExpr)(), Info,
2366 POK != PartialOrderingKind::None, Deduced, HasDeducedAnyParam);
2369 if (
auto Result = DeduceMatrixArg(MP->getRowExpr(), MA,
2375 return DeduceMatrixArg(MP->getColumnExpr(), MA,
2383 case Type::DependentAddressSpace: {
2389 S, TemplateParams, ASP->getPointeeType(), ASA->getPointeeType(),
2391 false, HasDeducedAnyParam);
2402 S, TemplateParams, NTTP, ASA->getAddrSpaceExpr(), Info,
2403 POK != PartialOrderingKind::None, Deduced, HasDeducedAnyParam);
2413 S, TemplateParams, ASP->getPointeeType(),
2416 false, HasDeducedAnyParam);
2427 S, TemplateParams, NTTP, ArgAddressSpace, S.
Context.
IntTy,
true,
2428 Info, POK != PartialOrderingKind::None, Deduced,
2429 HasDeducedAnyParam);
2434 case Type::DependentBitInt: {
2438 if (IP->isUnsigned() != IA->isUnsigned())
2447 ArgSize = IA->getNumBits();
2450 S, TemplateParams, NTTP, ArgSize, S.
Context.
IntTy,
true, Info,
2451 POK != PartialOrderingKind::None, Deduced, HasDeducedAnyParam);
2455 if (IP->isUnsigned() != IA->isUnsigned())
2463 case Type::TypeOfExpr:
2465 case Type::DependentName:
2466 case Type::UnresolvedUsing:
2467 case Type::Decltype:
2468 case Type::UnaryTransform:
2469 case Type::DeducedTemplateSpecialization:
2470 case Type::DependentTemplateSpecialization:
2471 case Type::PackExpansion:
2473 case Type::ArrayParameter:
2474 case Type::HLSLAttributedResource:
2478 case Type::PackIndexing: {
2484 false, HasDeducedAnyParam);
2490 llvm_unreachable(
"Invalid Type Class!");
2498 bool *HasDeducedAnyParam) {
2505 switch (
P.getKind()) {
2507 llvm_unreachable(
"Null template argument in parameter list");
2512 S, TemplateParams,
P.getAsType(), A.
getAsType(), Info, Deduced, 0,
2514 : PartialOrderingKind::None,
2515 false, HasDeducedAnyParam);
2527 HasDeducedAnyParam);
2533 llvm_unreachable(
"caller should handle pack expansions");
2584 if (
const auto *ICE = dyn_cast<ImplicitCastExpr>(
E);
2585 ICE && ICE->getCastKind() == clang::CK_Dependent) {
2586 E = ICE->getSubExpr();
2588 S, TemplateParams, ICE->getType(),
E->
getType(), Info,
2591 : PartialOrderingKind::None,
2592 false, HasDeducedAnyParam);
2605 HasDeducedAnyParam);
2610 Deduced, HasDeducedAnyParam);
2626 llvm_unreachable(
"Unknown template argument kind");
2632 llvm_unreachable(
"Argument packs should be expanded by the caller!");
2635 llvm_unreachable(
"Invalid TemplateArgument Kind!");
2648 if (ArgIdx == Args.size())
2655 assert(ArgIdx == Args.size() - 1 &&
"Pack not at the end of argument list?");
2658 return ArgIdx < Args.size();
2664 bool FoundPackExpansion =
false;
2665 for (
const auto &A : Args) {
2666 if (FoundPackExpansion)
2674 if (A.isPackExpansion())
2675 FoundPackExpansion =
true;
2689 bool FoldPackParameter =
PackFold == PackFold::ParameterToArgument ||
2691 FoldPackArgument =
PackFold == PackFold::ArgumentToParameter ||
2705 for (
unsigned ArgIdx = 0,
ParamIdx = 0; ; ) {
2711 if (!Ps[
ParamIdx].isPackExpansion()) {
2716 return !FoldPackArgument && NumberOfArgumentsMustMatch
2720 if (As[ArgIdx].isPackExpansion()) {
2725 if (!FoldPackArgument)
2732 S, TemplateParams, Ps[
ParamIdx], Pattern, Info,
2740 if (Ps[
ParamIdx].isPackExpansion())
2746 S, TemplateParams, Ps[
ParamIdx], As[ArgIdx], Info,
2767 PackDeductionScope PackScope(S, TemplateParams, Deduced, Info, Pattern);
2773 PackScope.hasNextElement();
2775 if (!As[ArgIdx].isPackExpansion()) {
2776 if (!FoldPackParameter)
2778 if (FoldPackArgument)
2784 Deduced, HasDeducedAnyParam);
2788 PackScope.nextPackElement();
2793 return PackScope.finish();
2801 bool NumberOfArgumentsMustMatch) {
2802 return ::DeduceTemplateArguments(
2803 *
this, TemplateParams, Ps, As, Info, Deduced, NumberOfArgumentsMustMatch,
2804 false, PackFold::ParameterToArgument,
2813 bool PackExpansionMatchesPack =
false) {
2816 if (PackExpansionMatchesPack &&
X.isPackExpansion() && !Y.
isPackExpansion())
2817 X =
X.getPackExpansionPattern();
2822 switch (
X.getKind()) {
2824 llvm_unreachable(
"Comparing NULL template argument");
2847 return X.structurallyEquals(Y);
2850 llvm::FoldingSetNodeID XID, YID;
2851 X.getAsExpr()->Profile(XID, Context,
true);
2857 unsigned PackIterationSize =
X.pack_size();
2866 bool XHasMoreArg =
X.pack_size() > Y.
pack_size();
2867 if (!(XHasMoreArg &&
X.pack_elements().back().isPackExpansion()) &&
2868 !(!XHasMoreArg && Y.
pack_elements().back().isPackExpansion()))
2877 for (
unsigned i = 0; i < PackIterationSize; ++i)
2879 PackExpansionMatchesPack))
2885 llvm_unreachable(
"Invalid TemplateArgument Kind!");
2894 llvm_unreachable(
"Can't get a NULL template argument here");
2929 Builder.MakeTrivial(
Context, DTN->getQualifier(),
Loc);
2932 Builder.MakeTrivial(
Context, QTN->getQualifier(),
Loc);
2949 llvm_unreachable(
"Invalid TemplateArgument Kind!");
2967 unsigned ArgumentPackIndex) {
2993 CanonicalPackedArgsBuilder;
3001 "deduced nested pack");
3008 diag::err_template_arg_deduced_incomplete_pack)
3012 if (ConvertArg(InnerArg, SugaredPackedArgsBuilder.size()))
3017 CanonicalPackedArgsBuilder.push_back(
3023 if (SugaredPackedArgsBuilder.empty()) {
3028 if (
auto *NTTP = dyn_cast<NonTypeTemplateParmDecl>(Param)) {
3033 S.
SubstType(NTTP->getType(), Args, NTTP->getLocation(),
3034 NTTP->getDeclName()).isNull())
3036 }
else if (
auto *TTP = dyn_cast<TemplateTemplateParmDecl>(Param)) {
3050 S.
Context, CanonicalPackedArgsBuilder));
3054 return ConvertArg(Arg, 0);
3064template <
typename TemplateDeclT>
3066 Sema &S, TemplateDeclT *Template,
bool IsDeduced,
3070 unsigned NumAlreadyConverted,
bool *IsIncomplete) {
3073 for (
unsigned I = 0, N = TemplateParams->
size(); I != N; ++I) {
3082 PackDeductionScope(S, TemplateParams, Deduced, Info, I).finish();
3087 if (!Deduced[I].isNull()) {
3088 if (I < NumAlreadyConverted) {
3132 *IsIncomplete =
true;
3139 bool HasDefaultArg =
false;
3142 assert(isa<ClassTemplatePartialSpecializationDecl>(Template) ||
3143 isa<VarTemplatePartialSpecializationDecl>(Template));
3152 if (Rec->isLambda())
3153 if (
auto *Method = dyn_cast<CXXMethodDecl>(Rec->getDeclContext())) {
3155 ThisTypeQuals = Method->getMethodQualifiers();
3201 if (
auto *DC = dyn_cast<DeclContext>(
D))
3207 static constexpr bool value =
false;
3211 static constexpr bool value =
true;
3215 static constexpr bool value =
true;
3217template <
typename TemplateDeclT>
3232template <
typename TemplateDeclT>
3239 Template->getAssociatedConstraints(AssociatedConstraints);
3241 std::optional<ArrayRef<TemplateArgument>> Innermost;
3245 Innermost = CanonicalDeducedArgs;
3248 Template, Template->getDeclContext(),
false, Innermost,
3272template <
typename T>
3273static std::enable_if_t<IsPartialSpecialization<T>::value,
3276 Sema &S,
T *Partial,
bool IsPartialOrdering,
3292 S, Partial, IsPartialOrdering, Deduced, Info, CTAI,
3304 Info.
reset(SugaredDeducedArgumentList, CanonicalDeducedArgumentList);
3312 auto *Template = Partial->getSpecializedTemplate();
3314 Partial->getTemplateArgsAsWritten();
3325 if (
ParamIdx >= Partial->getTemplateParameters()->size())
3326 ParamIdx = Partial->getTemplateParameters()->size() - 1;
3329 Partial->getTemplateParameters()->getParam(
ParamIdx));
3331 Info.
FirstArg = (*PartialTemplArgInfo)[ArgIdx].getArgument();
3338 {},
false, InstCTAI,
3348 for (
unsigned I = 0,
E = TemplateParams->
size(); I !=
E; ++I) {
3351 IsPartialOrdering)) {
3362 if (!IsPartialOrdering) {
3403 while (!Stack.empty()) {
3404 auto &Xs = Stack.back();
3409 auto &
X = Xs.front();
3411 Stack.emplace_back(
X.getPackAsArray());
3412 Xs = Xs.drop_front();
3415 assert(!
X.isNull());
3422 auto [Ps,
P] = take(PsStack);
3423 auto [As, A] = take(AsStack);
3424 if (
P.isNull() && A.isNull())
3427 PA = A.isPackExpansion() ? A.getPackExpansionPattern() : A;
3429 if (!
P.isPackExpansion() && !A.isPackExpansion()) {
3432 (PsStack.empty() ? TemplateArgs.end()
3433 : PsStack.front().begin()) -
3434 TemplateArgs.begin()));
3439 if (
P.isPackExpansion()) {
3440 Ps = Ps.drop_front();
3443 if (A.isPackExpansion()) {
3444 As = As.drop_front();
3448 Ps = Ps.drop_front(
P.isPackExpansion() ? 0 : 1);
3449 As = As.drop_front(A.isPackExpansion() && !
P.isPackExpansion() ? 0 : 1);
3451 assert(PsStack.empty());
3452 assert(AsStack.empty());
3482 S, TD,
false, Deduced, Info, CTAI,
3495template <
typename T>
3496static std::enable_if_t<IsPartialSpecialization<T>::value,
3501 if (Partial->isInvalidDecl())
3520 Deduced.resize(Partial->getTemplateParameters()->size());
3522 S, Partial->getTemplateParameters(),
3523 Partial->getTemplateArgs().asArray(), TemplateArgs, Info, Deduced,
3525 PackFold::ParameterToArgument,
3538 Result = ::FinishTemplateArgumentDeduction(S, Partial,
3540 TemplateArgs, Deduced, Info);
3556 return ::DeduceTemplateArguments(*
this, Partial, TemplateArgs, Info);
3562 return ::DeduceTemplateArguments(*
this, Partial, TemplateArgs, Info);
3572 if (
const auto *CTD = dyn_cast<ClassTemplateDecl>(TD)) {
3575 }
else if (
const auto *
AliasTemplate = dyn_cast<TypeAliasTemplateDecl>(TD)) {
3576 PType =
AliasTemplate->getTemplatedDecl()->getUnderlyingType();
3578 assert(
false &&
"Expected a class or alias template");
3597 return DeducedResult;
3607 Result = ::FinishTemplateArgumentDeduction(*this, TD, Deduced, Info);
3623 return Spec->getTemplateName().getAsTemplateDecl() !=
nullptr;
3649 if (ExplicitTemplateArgs.
size() == 0) {
3653 ParamTypes.push_back(
P->getType());
3683 ExplicitTemplateArgs, {},
3688 if (Index >= TemplateParams->
size())
3701 CanonicalExplicitArgumentList);
3713 unsigned PartiallySubstitutedPackIndex = -1u;
3721 if (!Expansions || Arg.
pack_size() < *Expansions) {
3731 assert(Proto &&
"Function template does not have a prototype?");
3739 SugaredExplicitArgumentList->
asArray(),
3749 nullptr, ExtParamInfos))
3766 ThisTypeQuals = Method->getMethodQualifiers();
3780 Diag(
Function->getLocation(), diag::err_kern_type_not_void_return)
3791 nullptr, ExtParamInfos))
3815 Deduced.reserve(TemplateParams->
size());
3816 for (
unsigned I = 0, N = SugaredExplicitArgumentList->
size(); I != N; ++I) {
3818 if (I == PartiallySubstitutedPackIndex)
3821 Deduced.push_back(Arg);
3890 if (AQuals == DeducedAQuals) {
3908 bool ObjCLifetimeConversion =
false;
3912 ObjCLifetimeConversion) ||
3958 if (PD->isParameterPack()) {
3959 unsigned NumExpansions =
3961 if (Idx + NumExpansions >
ParamIdx)
3963 Idx += NumExpansions;
3971 llvm_unreachable(
"parameter index would not be produced from template");
3983 return isa<CXXConstructorDecl>(
D)
3984 ? cast<CXXConstructorDecl>(
D)->getExplicitSpecifier()
3985 : cast<CXXConversionDecl>(
D)->getExplicitSpecifier();
3988 isa<CXXConstructorDecl>(
D)
3989 ? cast<CXXConstructorDecl>(
D)->setExplicitSpecifier(ES)
3990 : cast<CXXConversionDecl>(
D)->setExplicitSpecifier(ES);
4001 S, Info.
getLocation(), FunctionTemplate, DeducedArgs,
4023 llvm::function_ref<
bool()> CheckNonDependent) {
4043 bool IsIncomplete =
false;
4048 PartialOverloading ? &IsIncomplete :
nullptr);
4061 if (CheckNonDependent())
4069 Info.
reset(SugaredDeducedArgumentList, CanonicalDeducedArgumentList);
4092 CanonicalDeducedArgumentList &&
4112 if (!IsIncomplete) {
4128 if (isa<CXXConstructorDecl, CXXConversionDecl>(
Specialization)) {
4137 if (OriginalCallArgs) {
4142 llvm::SmallDenseMap<std::pair<unsigned, QualType>,
QualType> DeducedATypes;
4143 for (
unsigned I = 0, N = OriginalCallArgs->size(); I != N; ++I) {
4147 unsigned ExplicitOffset =
4167 if (CacheEntry.
isNull()) {
4176 DeducedA = CacheEntry;
4191 auto [Pos, Inserted] =
4205 if (S.
getLangOpts().CPlusPlus14 && Fn->getReturnType()->isUndeducedType() &&
4210 if (Method->isImplicitObjectMemberFunction()) {
4231 bool ParamWasReference,
4240 if (ParamWasReference)
4257 nullptr, FailedTSC))
4298 if (ArgType.
isNull())
continue;
4318 Deduced(TemplateParams->
size());
4321 S, TemplateParams, ParamType, ArgType, Info, Deduced, TDF,
4322 PartialOrderingKind::None,
false,
4361 assert(Arg &&
"expected a non-null arg expression");
4363 ParamRefType !=
nullptr, FailedTSC);
4371 assert(Arg &&
"expected a non-null arg expression");
4426 (isa<PointerType>(ParamType) &&
4445 bool DecomposedParam,
unsigned ArgIdx,
unsigned TDF,
4470 ElTy = ArrTy->getElementType();
4480 if (isa<DesignatedInitExpr>(
E))
4487 S, TemplateParams, 0, ElTy,
E->
getType(),
4489 OriginalCallArgs,
true, ArgIdx, TDF);
4497 if (
auto *DependentArrTy = dyn_cast_or_null<DependentSizedArrayType>(ArrTy)) {
4508 S, TemplateParams, NTTP, llvm::APSInt(Size),
T,
4509 true, Info,
false, Deduced,
4528 bool DecomposedParam,
unsigned ArgIdx,
unsigned TDF,
4531 QualType OrigParamType = ParamType;
4536 S, TemplateParams, FirstInnerIndex, ParamType, ArgType,
4537 ArgClassification, Arg, TDF, FailedTSC))
4541 if (
InitListExpr *ILE = dyn_cast_if_present<InitListExpr>(Arg))
4543 Deduced, OriginalCallArgs, ArgIdx, TDF);
4551 OriginalCallArgs.push_back(
4554 S, TemplateParams, ParamType, ArgType, Info, Deduced, TDF,
4555 PartialOrderingKind::None,
false,
4563 bool PartialOverloading,
bool AggregateDeductionCandidate,
4571 unsigned NumParams =
Function->getNumParams();
4572 bool HasExplicitObject =
false;
4573 int ExplicitObjectOffset = 0;
4574 if (
Function->hasCXXExplicitFunctionObjectParameter()) {
4575 HasExplicitObject =
true;
4576 ExplicitObjectOffset = 1;
4585 if (Args.size() <
Function->getMinRequiredExplicitArguments() &&
4586 !PartialOverloading)
4589 PartialOverloading)) {
4591 if (Proto->isTemplateVariadic())
4593 else if (!Proto->isVariadic())
4604 unsigned NumExplicitlySpecified = 0;
4605 if (ExplicitTemplateArgs) {
4608 Result = SubstituteExplicitTemplateArguments(
4609 FunctionTemplate, *ExplicitTemplateArgs, Deduced, ParamTypes, nullptr,
4615 NumExplicitlySpecified = Deduced.size();
4618 for (
unsigned I = 0; I != NumParams; ++I)
4619 ParamTypes.push_back(
Function->getParamDecl(I)->getType());
4625 auto DeduceCallArgument = [&](
QualType ParamType,
unsigned ArgIdx,
4626 bool ExplicitObjectArgument) {
4634 if (ExplicitObjectArgument) {
4637 *
this, TemplateParams, FirstInnerIndex, ParamType, ObjectType,
4638 ObjectClassification,
4639 nullptr, Info, Deduced, OriginalCallArgs,
4645 *
this, TemplateParams, FirstInnerIndex, ParamType,
4646 Args[ArgIdx]->getType(), Args[ArgIdx]->Classify(
getASTContext()),
4647 Args[ArgIdx], Info, Deduced, OriginalCallArgs,
false,
4652 Deduced.resize(TemplateParams->
size());
4654 for (
unsigned ParamIdx = 0, NumParamTypes = ParamTypes.size(), ArgIdx = 0;
4659 dyn_cast<PackExpansionType>(ParamType);
4660 if (!ParamExpansion) {
4662 if (ArgIdx >= Args.size() && !(HasExplicitObject &&
ParamIdx == 0))
4665 ParamTypesForArgChecking.push_back(ParamType);
4667 if (
ParamIdx == 0 && HasExplicitObject) {
4671 if (
auto Result = DeduceCallArgument(ParamType, 0,
4678 if (
auto Result = DeduceCallArgument(ParamType, ArgIdx++,
4686 bool IsTrailingPack =
ParamIdx + 1 == NumParamTypes;
4689 PackDeductionScope PackScope(*
this, TemplateParams, Deduced, Info,
4691 AggregateDeductionCandidate && IsTrailingPack);
4709 if (IsTrailingPack || PackScope.hasFixedArity()) {
4710 for (; ArgIdx < Args.size() && PackScope.hasNextElement();
4711 PackScope.nextPackElement(), ++ArgIdx) {
4712 ParamTypesForArgChecking.push_back(ParamPattern);
4713 if (
auto Result = DeduceCallArgument(ParamPattern, ArgIdx,
4722 std::optional<unsigned> NumExpansions =
4724 if (NumExpansions && !PackScope.isPartiallyExpanded()) {
4725 for (
unsigned I = 0; I != *NumExpansions && ArgIdx < Args.size();
4727 ParamTypesForArgChecking.push_back(ParamPattern);
4730 PackScope.nextPackElement();
4732 }
else if (!IsTrailingPack && !PackScope.isPartiallyExpanded() &&
4733 PackScope.isDeducedFromEarlierParameter()) {
4746 std::optional<unsigned> ArgPosAfterSubstitution =
4747 PackScope.getSavedPackSizeIfAllEqual();
4748 if (!ArgPosAfterSubstitution)
4751 unsigned PackArgEnd = ArgIdx + *ArgPosAfterSubstitution;
4752 for (; ArgIdx < PackArgEnd && ArgIdx < Args.size(); ArgIdx++) {
4753 ParamTypesForArgChecking.push_back(ParamPattern);
4755 DeduceCallArgument(ParamPattern, ArgIdx,
4760 PackScope.nextPackElement();
4767 if (
auto Result = PackScope.finish();
4778 Result = FinishTemplateArgumentDeduction(
4779 FunctionTemplate, Deduced, NumExplicitlySpecified, Specialization, Info,
4780 &OriginalCallArgs, PartialOverloading, PartialOrdering,
4782 ContextRAII SavedContext(*this, CallingCtx);
4783 return CheckNonDependent(ParamTypesForArgChecking);
4791 bool AdjustExceptionSpec) {
4792 if (ArgFunctionType.
isNull())
4793 return ArgFunctionType;
4798 bool Rebuild =
false;
4801 if (EPI.ExtInfo.getCC() != CC) {
4802 EPI.
ExtInfo = EPI.ExtInfo.withCallingConv(CC);
4806 bool NoReturn = FunctionTypeP->getNoReturnAttr();
4807 if (EPI.ExtInfo.getNoReturn() != NoReturn) {
4808 EPI.ExtInfo = EPI.ExtInfo.withNoReturn(NoReturn);
4812 if (AdjustExceptionSpec && (FunctionTypeP->hasExceptionSpec() ||
4814 EPI.ExceptionSpec = FunctionTypeP->getExtProtoInfo().ExceptionSpec;
4819 return ArgFunctionType;
4829 bool IsAddressOfFunction) {
4841 unsigned NumExplicitlySpecified = 0;
4843 if (ExplicitTemplateArgs) {
4846 Result = SubstituteExplicitTemplateArguments(
4847 FunctionTemplate, *ExplicitTemplateArgs, Deduced, ParamTypes,
4848 &FunctionType, Info);
4853 NumExplicitlySpecified = Deduced.size();
4859 if (!IsAddressOfFunction)
4868 Deduced.resize(TemplateParams->
size());
4872 bool HasDeducedReturnType =
false;
4874 Function->getReturnType()->getContainedAutoType()) {
4876 HasDeducedReturnType =
true;
4884 *
this, TemplateParams,
FunctionType, ArgFunctionType, Info, Deduced,
4885 TDF, PartialOrderingKind::None,
false,
4893 Result = FinishTemplateArgumentDeduction(
4894 FunctionTemplate, Deduced, NumExplicitlySpecified, Specialization, Info,
4903 if (HasDeducedReturnType && IsAddressOfFunction &&
4924 if (!IsAddressOfFunction) {
4930 if (HasDeducedReturnType) {
4939 if (!ArgFunctionType.
isNull()) {
4941 SpecializationType, ArgFunctionType)
4943 SpecializationType, ArgFunctionType)) {
4964 bool IsReferenceP =
P->isReferenceType();
4971 P = PRef->getPointeeType();
4981 if (!IsReferenceP) {
4983 P =
P.getUnqualifiedType();
4990 assert(!A->
isReferenceType() &&
"Reference types were handled above");
4995 if (
P->isArrayType())
5000 else if (
P->isFunctionType())
5005 P =
P.getUnqualifiedType();
5027 Deduced.resize(TemplateParams->
size());
5056 ParamType, ObjectType, ObjectClassification,
5057 nullptr, Info, Deduced, OriginalCallArgs,
5064 *
this, TemplateParams,
P, A, Info, Deduced, TDF,
5065 PartialOrderingKind::None,
false,
5076 Result = FinishTemplateArgumentDeduction(
5077 ConversionTemplate, Deduced, 0, ConversionSpecialized, Info,
5078 &OriginalCallArgs, false,
5081 Specialization = cast_or_null<CXXConversionDecl>(ConversionSpecialized);
5090 bool IsAddressOfFunction) {
5093 IsAddressOfFunction);
5097 struct DependentAuto {
bool IsPack; };
5101 class SubstituteDeducedTypeTransform :
5104 bool ReplacementIsPack;
5109 SubstituteDeducedTypeTransform(
Sema &SemaRef, DependentAuto DA)
5111 ReplacementIsPack(DA.IsPack), UseTypeSugar(
true) {}
5113 SubstituteDeducedTypeTransform(
Sema &SemaRef,
QualType Replacement,
5114 bool UseTypeSugar =
true)
5116 Replacement(Replacement), ReplacementIsPack(
false),
5117 UseTypeSugar(UseTypeSugar) {}
5120 assert(isa<TemplateTypeParmType>(Replacement) &&
5121 "unexpected unsugared replacement kind");
5139 return TransformDesugared(TLB, TL);
5141 QualType Result = SemaRef.Context.getAutoType(
5150 QualType TransformDeducedTemplateSpecializationType(
5153 return TransformDesugared(TLB, TL);
5155 QualType Result = SemaRef.Context.getDeducedTemplateSpecializationType(
5157 Replacement, Replacement.isNull());
5175 return inherited::TransformExceptionSpec(
Loc, ESI, Exceptions, Changed);
5183 return TransformType(TLB, TL);
5199 Deduced,
TypeLoc.getNameLoc())));
5200 for (
unsigned I = 0,
C =
TypeLoc.getNumArgs(); I !=
C; ++I)
5222 S.
getASTContext(), Concept->getDeclContext(), Concept->getLocation(),
5230 llvm::raw_string_ostream OS(Buf);
5231 OS <<
"'" << Concept->getName();
5232 if (
TypeLoc.hasExplicitTemplateArgs()) {
5235 Type.getTypeConstraintConcept()->getTemplateParameters());
5239 diag::err_placeholder_constraints_not_satisfied)
5250 bool IgnoreConstraints,
5253 if (
Init->containsErrors())
5266 DependentAuto DependentResult = {
5269 if (!DependentDeduction &&
5271 Init->containsUnexpandedParameterPack())) {
5272 Result = SubstituteDeducedTypeTransform(*
this, DependentResult).Apply(
Type);
5273 assert(!
Result.isNull() &&
"substituting DependentTy can't fail");
5278 auto *String = dyn_cast<StringLiteral>(
Init);
5280 Diag(
Type.getBeginLoc(), diag::ext_c23_auto_non_plain_identifier);
5282 Result = SubstituteDeducedTypeTransform(*
this, DependentResult).Apply(TL);
5283 assert(!
Result.isNull() &&
"substituting DependentTy can't fail");
5289 Diag(
Type.getBeginLoc(), diag::ext_c23_auto_non_plain_identifier);
5292 auto *InitList = dyn_cast<InitListExpr>(
Init);
5294 Diag(
Init->getBeginLoc(), diag::err_auto_init_list_from_c)
5306 if (
Init->isTypeDependent()) {
5308 SubstituteDeducedTypeTransform(*
this, DependentResult).Apply(
Type);
5309 assert(!
Result.isNull() &&
"substituting DependentTy can't fail");
5321 Diag(
Init->getBeginLoc(), diag::err_decltype_auto_initializer_list);
5334 nullptr,
false,
false,
false);
5348 for (
Expr *
Init : InitList->inits()) {
5351 if (isa<DesignatedInitExpr>(
Init))
5354 *
this, TemplateParamsSt.get(), 0, TemplArg,
Init->getType(),
5363 <<
Init->getSourceRange();
5366 return DeductionFailed(TDK);
5371 DeducedFromInitRange =
Init->getSourceRange();
5375 Diag(
Loc, diag::err_auto_bitfield);
5379 SubstituteDeducedTypeTransform(*
this, TemplArg).Apply(
Type);
5380 assert(!FuncParam.
isNull() &&
5381 "substituting template parameter for 'auto' failed");
5383 *
this, TemplateParamsSt.get(), 0, FuncParam,
Init->getType(),
5386 false, 0, 0, FailedTSC);
5388 return DeductionFailed(TDK);
5425 assert((
bool)InitList == OriginalArg.DecomposedParam &&
5426 "decomposed non-init-list in auto deduction?");
5431 return DeductionFailed(TDK);
5441 return SubstituteDeducedTypeTransform(*
this, TypeToReplaceAuto)
5442 .TransformType(TypeWithAuto);
5448 return SubstituteDeducedTypeTransform(*
this, TypeToReplaceAuto)
5449 .TransformType(TypeWithAuto);
5453 return SubstituteDeducedTypeTransform(*
this, DependentAuto{
false})
5454 .TransformType(TypeWithAuto);
5459 return SubstituteDeducedTypeTransform(*
this, DependentAuto{
false})
5460 .TransformType(TypeWithAuto);
5465 return SubstituteDeducedTypeTransform(*
this, TypeToReplaceAuto,
5467 .TransformType(TypeWithAuto);
5472 return SubstituteDeducedTypeTransform(*
this, TypeToReplaceAuto,
5474 .TransformType(TypeWithAuto);
5479 if (isa<InitListExpr>(
Init))
5482 ? diag::err_init_capture_deduction_failure_from_init_list
5483 : diag::err_auto_var_deduction_failure_from_init_list)
5487 VDecl->
isInitCapture() ? diag::err_init_capture_deduction_failure
5488 : diag::err_auto_var_deduction_failure)
5490 <<
Init->getSourceRange();
5522 "failed to deduce lambda return type");
5549 Diag(
Loc, diag::err_auto_fn_used_before_defined) << FD;
5553 return StillUndeduced;
5597 "expected a member function with no explicit object parameter");
5613 bool IsIncompleteSubstitution =
false;
5619 if (InstP.
isNull() && !IsIncompleteSubstitution)
5621 if (!CheckConsistency)
5623 if (IsIncompleteSubstitution)
5628 if (
auto *PA = dyn_cast<PackExpansionType>(A);
5629 PA && !isa<PackExpansionType>(InstP))
5630 A = PA->getPattern();
5652 bool IsIncomplete =
false;
5655 S, FTD,
true, Deduced, Info, CTAI,
5667 Info.
reset(SugaredDeducedArgumentList, CanonicalDeducedArgumentList);
5692 assert(Proto1 && Proto2 &&
"Function templates must have prototypes");
5708 Proto1->
isVariadic() == Proto2->isVariadic() &&
5709 "shouldn't partial order functions with different qualifiers in a "
5710 "context where the function type is used");
5712 assert(Args1.empty() && Args2.empty() &&
5713 "Only call context should have arguments");
5715 Args2 = Proto2->getParamTypes();
5722 bool HasDeducedAnyParamFromReturnType =
false;
5725 S, TemplateParams, Proto2->getReturnType(), Proto1->
getReturnType(),
5726 Info, Deduced,
TDF_None, PartialOrderingKind::Call,
5728 &HasDeducedAnyParamFromReturnType) !=
5733 llvm::SmallBitVector HasDeducedParam;
5735 HasDeducedParam.resize(Args2.size());
5737 TDF_None, PartialOrderingKind::Call,
5739 &HasDeducedParam) !=
5751 bool AtLeastAsSpecialized;
5753 AtLeastAsSpecialized =
5754 ::FinishTemplateArgumentDeduction(
5755 S, FT2, Deduced, Info,
5756 [&](Sema &S, FunctionTemplateDecl *FTD,
5757 ArrayRef<TemplateArgument> DeducedArgs) {
5762 if (TPOC != TPOC_Call) {
5763 if (auto TDR = ::CheckDeductionConsistency(
5764 S, FTD, -1, Proto2->getReturnType(),
5765 Proto1->getReturnType(), DeducedArgs,
5766 HasDeducedAnyParamFromReturnType);
5767 TDR != TemplateDeductionResult::Success)
5771 if (TPOC == TPOC_Conversion)
5772 return TemplateDeductionResult::Success;
5774 return ::DeduceForEachType(
5775 S, TemplateParams, Args2, Args1, Info, Deduced,
5776 PartialOrderingKind::Call, true,
5777 [&](Sema &S, TemplateParameterList *, int ParamIdx,
5778 int ArgIdx, QualType P, QualType A,
5779 TemplateDeductionInfo &Info,
5780 SmallVectorImpl<DeducedTemplateArgument> &Deduced,
5781 PartialOrderingKind) {
5783 ArgIdx -= Args1Offset;
5784 return ::CheckDeductionConsistency(
5785 S, FTD, ArgIdx, P, A, DeducedArgs,
5786 HasDeducedParam[ParamIdx]);
5790 if (!AtLeastAsSpecialized)
5799 unsigned ArgIdx = 0, NumArgs = Deduced.size();
5800 for (; ArgIdx != NumArgs; ++ArgIdx)
5801 if (Deduced[ArgIdx].isNull())
5804 if (ArgIdx == NumArgs) {
5811 llvm::SmallBitVector UsedParameters(TemplateParams->size());
5814 for (
unsigned I = 0, N = Args2.size(); I != N; ++I)
5816 TemplateParams->getDepth(), UsedParameters);
5822 TemplateParams->getDepth(), UsedParameters);
5848 false, TemplateParams->getDepth(), UsedParameters);
5852 for (; ArgIdx != NumArgs; ++ArgIdx)
5855 if (Deduced[ArgIdx].isNull() && UsedParameters[ArgIdx])
5869 bool ShouldConvert1 =
false;
5870 bool ShouldConvert2 =
false;
5871 bool Args1Offset =
false;
5872 bool Args2Offset =
false;
5883 const CXXMethodDecl *Method1 = dyn_cast<CXXMethodDecl>(FD1);
5884 const CXXMethodDecl *Method2 = dyn_cast<CXXMethodDecl>(FD2);
5895 bool NonStaticMethod1 = Method1 && !Method1->isStatic(),
5896 NonStaticMethod2 = Method2 && !Method2->
isStatic();
5899 Params2Begin = Proto2->param_type_begin();
5901 size_t NumComparedArguments = NumCallArguments1;
5904 (NonStaticMethod1 && NonStaticMethod2) ||
5905 (OO !=
OO_None && OO != OO_Call && OO != OO_Subscript)) {
5907 NonStaticMethod1 && !Method1->hasCXXExplicitFunctionObjectParameter();
5910 NumComparedArguments += 1;
5912 if (ShouldConvert1) {
5916 : Proto2->param_type_begin()[0]->isRValueReferenceType();
5919 RawObj1Ty, IsRValRef2);
5920 Args1.push_back(Obj1Ty);
5923 if (ShouldConvert2) {
5926 ? Method1->getRefQualifier() ==
RQ_RValue
5930 RawObj2Ty, IsRValRef1);
5931 Args2.push_back(Obj2Ty);
5935 if (NonStaticMethod1 && Method1->hasCXXExplicitFunctionObjectParameter())
5940 Args1.insert(Args1.end(), Params1Begin, Proto1->
param_type_end());
5941 Args2.insert(Args2.end(), Params2Begin, Proto2->param_type_end());
5946 Args1.resize(std::min(Args1.size(), NumComparedArguments));
5947 Args2.resize(std::min(Args2.size(), NumComparedArguments));
5950 std::reverse(Args2.begin(), Args2.end());
5952 assert(!
Reversed &&
"Only call context could have reversed arguments");
5955 Args2, Args2Offset);
5957 Args1, Args1Offset);
5961 if (Better1 != Better2)
5962 return Better1 ? FT1 : FT2;
5964 if (!Better1 && !Better2)
5973 Param1.reserve(FD1->
param_size() + ShouldConvert1);
5975 Param1.push_back(Obj1Ty);
5977 Param1.push_back(
P->getType());
5980 Param2.reserve(FD2->
param_size() + ShouldConvert2);
5982 Param2.push_back(Obj2Ty);
5984 Param2.push_back(
P->getType());
5986 unsigned NumParams1 = Param1.size();
5987 unsigned NumParams2 = Param2.size();
5993 if (Variadic1 != Variadic2) {
5994 if (Variadic1 && NumParams1 > NumParams2)
5996 if (Variadic2 && NumParams2 > NumParams1)
6002 for (
int i = 0, e = std::min(NumParams1, NumParams2); i < e; ++i) {
6003 QualType T1 = Param1[i].getCanonicalType();
6004 QualType T2 = Param2[i].getCanonicalType();
6005 auto *TST1 = dyn_cast<TemplateSpecializationType>(T1);
6006 auto *TST2 = dyn_cast<TemplateSpecializationType>(T2);
6011 assert(TST1->template_arguments().size() ==
6012 TST2->template_arguments().size());
6017 bool IsPackExpansion1 =
6019 bool IsPackExpansion2 =
6021 if (PackSize1 != PackSize2 && IsPackExpansion1 != IsPackExpansion2) {
6022 if (PackSize1 > PackSize2 && IsPackExpansion1)
6024 if (PackSize1 < PackSize2 && IsPackExpansion2)
6046 if (TPL1->
size() != TPL2->
size() || NumParams1 != NumParams2)
6062 for (
unsigned i = 0; i < NumParams1; ++i)
6078 bool AtLeastAsConstrained1, AtLeastAsConstrained2;
6083 if (AtLeastAsConstrained1 == AtLeastAsConstrained2)
6085 return AtLeastAsConstrained1 ? FT1 : FT2;
6093 bool Complain,
QualType TargetType) {
6094 if (SpecBegin == SpecEnd) {
6102 if (SpecBegin + 1 == SpecEnd)
6109 = cast<FunctionDecl>(*Best)->getPrimaryTemplate();
6110 assert(BestTemplate &&
"Not a function template specialization?");
6113 = cast<FunctionDecl>(*I)->getPrimaryTemplate();
6114 assert(Challenger &&
"Not a function template specialization?");
6119 BestTemplate = Challenger;
6125 bool Ambiguous =
false;
6128 = cast<FunctionDecl>(*I)->getPrimaryTemplate();
6150 const auto *FD = cast<FunctionDecl>(*I);
6152 FD->getPrimaryTemplate()->getTemplateParameters(),
6153 *FD->getTemplateSpecializationArgs());
6154 if (!TargetType.
isNull())
6156 Diag((*I)->getLocation(), PD);
6166 "not for function templates");
6168 isa<CXXConversionDecl>(FD1));
6170 isa<CXXConversionDecl>(FD2));
6183 bool AtLeastAsConstrained1, AtLeastAsConstrained2;
6188 if (AtLeastAsConstrained1 == AtLeastAsConstrained2)
6190 return AtLeastAsConstrained1 ? FD1 : FD2;
6200template<
typename TemplateLikeDecl>
6202 TemplateLikeDecl *P2,
6231 Deduced.resize(P2->getTemplateParameters()->size());
6233 S, P2->getTemplateParameters(), T2, T1, Info, Deduced,
TDF_None,
6234 PartialOrderingKind::Call,
false,
6245 const auto *TST1 = cast<TemplateSpecializationType>(T1);
6251 Result = ::FinishTemplateArgumentDeduction(
6252 S, P2, true, TST1->template_arguments(), Deduced,
6269 template <
typename T1,
typename T2,
6270 std::enable_if_t<std::is_same_v<T1, T2>,
bool> =
true>
6271 T2 *operator()(T1 *, T2 *P2) {
6274 template <
typename T1,
typename T2,
6275 std::enable_if_t<!std::is_same_v<T1, T2>,
bool> =
true>
6276 T1 *operator()(T1 *, T2 *) {
6282struct TemplateArgumentListAreEqual {
6284 TemplateArgumentListAreEqual(
ASTContext &Ctx) : Ctx(Ctx) {}
6286 template <
typename T1,
typename T2,
6287 std::enable_if_t<std::is_same_v<T1, T2>,
bool> =
true>
6288 bool operator()(T1 *PS1, T2 *PS2) {
6290 Args2 = PS2->getTemplateArgs().asArray();
6292 for (
unsigned I = 0,
E = Args1.size(); I <
E; ++I) {
6296 llvm::FoldingSetNodeID IDA, IDB;
6297 Args1[I].Profile(IDA, Ctx);
6298 Args2[I].Profile(IDB, Ctx);
6305 template <
typename T1,
typename T2,
6306 std::enable_if_t<!std::is_same_v<T1, T2>,
bool> =
true>
6307 bool operator()(T1 *Spec, T2 *Primary) {
6309 Args2 = Primary->getInjectedTemplateArgs(Ctx);
6311 for (
unsigned I = 0,
E = Args1.size(); I <
E; ++I) {
6315 llvm::FoldingSetNodeID IDA, IDB;
6316 Args1[I].Profile(IDA, Ctx);
6350template <
typename TemplateLikeDecl,
typename PrimaryDel>
6351static TemplateLikeDecl *
6354 constexpr bool IsMoreSpecialThanPrimaryCheck =
6355 !std::is_same_v<TemplateLikeDecl, PrimaryDel>;
6358 if (IsMoreSpecialThanPrimaryCheck && !Better1)
6362 if (IsMoreSpecialThanPrimaryCheck && !Better2)
6368 if (Better1 != Better2)
6369 return Better1 ? P1 : GetP2()(P1, P2);
6371 if (!Better1 && !Better2)
6376 auto *TST1 = cast<TemplateSpecializationType>(T1);
6377 auto *TST2 = cast<TemplateSpecializationType>(T2);
6380 assert(TST1->template_arguments().size() ==
6381 TST2->template_arguments().size());
6386 bool IsPackExpansion1 =
6388 bool IsPackExpansion2 =
6390 if (PackSize1 != PackSize2 && IsPackExpansion1 != IsPackExpansion2) {
6391 if (PackSize1 > PackSize2 && IsPackExpansion1)
6392 return GetP2()(P1, P2);
6393 if (PackSize1 < PackSize2 && IsPackExpansion2)
6422 if (!TemplateArgumentListAreEqual(S.
getASTContext())(P1, P2))
6426 P1->getAssociatedConstraints(AC1);
6427 P2->getAssociatedConstraints(AC2);
6428 bool AtLeastAsConstrained1, AtLeastAsConstrained2;
6430 (IsMoreSpecialThanPrimaryCheck && !AtLeastAsConstrained1))
6434 if (AtLeastAsConstrained1 == AtLeastAsConstrained2)
6436 return AtLeastAsConstrained1 ? P1 : GetP2()(P1, P2);
6471 "the partial specializations being compared should specialize"
6472 " the same template.");
6535 for (
unsigned I = 0, N =
P->size(); I != N; ++I) {
6544 Arg,
QualType(),
P->getParam(I)->getLocation()));
6560 if (MatchedPackOnParmToNonPackOnArg)
6567 Deduced.resize(A->
size());
6581 *
this, A, AArgs, PArgs, Info, Deduced,
6586 if (MatchedPackOnParmToNonPackOnArg &&
6588 *MatchedPackOnParmToNonPackOnArg =
true;
6592 Diag(AArg->
getLocation(), diag::err_template_param_list_different_arity)
6593 << (A->
size() >
P->size()) <<
true
6602 diag::err_inconsistent_deduction)
6623 llvm_unreachable(
"Unexpected Result");
6630 TDK = ::FinishTemplateArgumentDeduction(
6631 *this, AArg, true, PArgs, Deduced, Info);
6640 llvm_unreachable(
"Unexpected NonDeducedMismatch");
6663 llvm_unreachable(
"Unexpected Result");
6665 llvm_unreachable(
"Unexpected TDK");
6670 llvm::SmallBitVector &
Used;
6673 MarkUsedTemplateParameterVisitor(llvm::SmallBitVector &
Used,
6678 if (
T->getDepth() == Depth)
6679 Used[
T->getIndex()] =
true;
6683 bool TraverseTemplateName(
TemplateName Template)
override {
6684 if (
auto *TTP = llvm::dyn_cast_or_null<TemplateTemplateParmDecl>(
6686 if (TTP->getDepth() == Depth)
6687 Used[TTP->getIndex()] =
true;
6693 if (
auto *NTTP = dyn_cast<NonTypeTemplateParmDecl>(
E->getDecl()))
6694 if (NTTP->getDepth() == Depth)
6695 Used[NTTP->getIndex()] =
true;
6708 llvm::SmallBitVector &
Used) {
6710 MarkUsedTemplateParameterVisitor(
Used, Depth)
6711 .TraverseStmt(
const_cast<Expr *
>(
E));
6717 E = Expansion->getPattern();
6739 llvm::SmallBitVector &
Used) {
6746 OnlyDeduced, Depth,
Used);
6756 llvm::SmallBitVector &
Used) {
6757 if (
TemplateDecl *Template = Name.getAsTemplateDecl()) {
6759 = dyn_cast<TemplateTemplateParmDecl>(Template)) {
6760 if (TTP->getDepth() == Depth)
6761 Used[TTP->getIndex()] =
true;
6780 llvm::SmallBitVector &
Used) {
6798 case Type::BlockPointer:
6806 case Type::LValueReference:
6807 case Type::RValueReference:
6815 case Type::MemberPointer: {
6820 OnlyDeduced, Depth,
Used);
6824 case Type::DependentSizedArray:
6826 cast<DependentSizedArrayType>(
T)->getSizeExpr(),
6827 OnlyDeduced, Depth,
Used);
6831 case Type::ConstantArray:
6832 case Type::IncompleteArray:
6833 case Type::ArrayParameter:
6835 cast<ArrayType>(
T)->getElementType(),
6836 OnlyDeduced, Depth,
Used);
6839 case Type::ExtVector:
6841 cast<VectorType>(
T)->getElementType(),
6842 OnlyDeduced, Depth,
Used);
6845 case Type::DependentVector: {
6846 const auto *VecType = cast<DependentVectorType>(
T);
6853 case Type::DependentSizedExtVector: {
6855 = cast<DependentSizedExtVectorType>(
T);
6863 case Type::DependentAddressSpace: {
6865 cast<DependentAddressSpaceType>(
T);
6867 OnlyDeduced, Depth,
Used);
6870 OnlyDeduced, Depth,
Used);
6874 case Type::ConstantMatrix: {
6881 case Type::DependentSizedMatrix: {
6892 case Type::FunctionProto: {
6896 for (
unsigned I = 0, N = Proto->
getNumParams(); I != N; ++I) {
6901 if (!OnlyDeduced || I + 1 == N ||
6919 case Type::TemplateTypeParm: {
6926 case Type::SubstTemplateTypeParmPack: {
6928 = cast<SubstTemplateTypeParmPackType>(
T);
6932 OnlyDeduced, Depth,
Used);
6936 case Type::InjectedClassName:
6937 T = cast<InjectedClassNameType>(
T)->getInjectedSpecializationType();
6940 case Type::TemplateSpecialization: {
6942 = cast<TemplateSpecializationType>(
T);
6962 cast<ComplexType>(
T)->getElementType(),
6963 OnlyDeduced, Depth,
Used);
6969 cast<AtomicType>(
T)->getValueType(),
6970 OnlyDeduced, Depth,
Used);
6973 case Type::DependentName:
6976 cast<DependentNameType>(
T)->getQualifier(),
6977 OnlyDeduced, Depth,
Used);
6980 case Type::DependentTemplateSpecialization: {
6994 = cast<DependentTemplateSpecializationType>(
T);
6997 OnlyDeduced, Depth,
Used);
7007 OnlyDeduced, Depth,
Used);
7010 case Type::TypeOfExpr:
7013 cast<TypeOfExprType>(
T)->getUnderlyingExpr(),
7014 OnlyDeduced, Depth,
Used);
7017 case Type::Decltype:
7020 cast<DecltypeType>(
T)->getUnderlyingExpr(),
7021 OnlyDeduced, Depth,
Used);
7024 case Type::PackIndexing:
7027 OnlyDeduced, Depth,
Used);
7029 OnlyDeduced, Depth,
Used);
7033 case Type::UnaryTransform:
7037 OnlyDeduced, Depth,
Used);
7040 case Type::PackExpansion:
7042 cast<PackExpansionType>(
T)->getPattern(),
7043 OnlyDeduced, Depth,
Used);
7047 case Type::DeducedTemplateSpecialization:
7049 cast<DeducedType>(
T)->getDeducedType(),
7050 OnlyDeduced, Depth,
Used);
7052 case Type::DependentBitInt:
7054 cast<DependentBitIntType>(
T)->getNumBitsExpr(),
7055 OnlyDeduced, Depth,
Used);
7058 case Type::HLSLAttributedResource:
7060 Ctx, cast<HLSLAttributedResourceType>(
T)->getWrappedType(), OnlyDeduced,
7062 if (cast<HLSLAttributedResourceType>(
T)->hasContainedType())
7064 Ctx, cast<HLSLAttributedResourceType>(
T)->getContainedType(),
7065 OnlyDeduced, Depth,
Used);
7070 case Type::VariableArray:
7071 case Type::FunctionNoProto:
7074 case Type::ObjCInterface:
7075 case Type::ObjCObject:
7076 case Type::ObjCObjectPointer:
7077 case Type::UnresolvedUsing:
7080#define TYPE(Class, Base)
7081#define ABSTRACT_TYPE(Class, Base)
7082#define DEPENDENT_TYPE(Class, Base)
7083#define NON_CANONICAL_TYPE(Class, Base) case Type::Class:
7084#include "clang/AST/TypeNodes.inc"
7096 llvm::SmallBitVector &
Used) {
7114 OnlyDeduced, Depth,
Used);
7132 llvm::SmallBitVector &
Used) {
7138 bool OnlyDeduced,
unsigned Depth,
7139 llvm::SmallBitVector &
Used) {
7148 for (
unsigned I = 0, N = TemplateArgs.
size(); I != N; ++I)
7155 llvm::SmallBitVector &Deduced) {
7159 Deduced.resize(TemplateParams->
size());
7162 for (
unsigned I = 0, N =
Function->getNumParams(); I != N; ++I)
7164 true, TemplateParams->
getDepth(), Deduced);
7175 llvm::SmallBitVector Deduced(TemplateParams->
size());
7179 return Deduced.any();
Defines the clang::ASTContext interface.
This file provides some common utility functions for processing Lambda related AST Constructs.
Provides definitions for the various language-specific address spaces.
static Decl::Kind getKind(const Decl *D)
Defines the C++ Decl subclasses, other than those for templates (found in DeclTemplate....
Defines the C++ template declaration subclasses.
Defines the ExceptionSpecificationType enumeration and various utility functions.
Defines the clang::Expr interface and subclasses for C++ expressions.
llvm::DenseSet< const void * > Visited
Forward-declares and imports various common LLVM datatypes that clang wants to use unqualified.
Defines the clang::LangOptions interface.
Implements a partial diagnostic that can be emitted anwyhere in a DiagnosticBuilder stream.
static QualType getUnderlyingType(const SubRegion *R)
static bool 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 bool isSameTemplateArg(ASTContext &Context, TemplateArgument X, const TemplateArgument &Y, bool PartialOrdering, bool PackExpansionMatchesPack=false)
Determine whether two template arguments are the same.
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 PartialOrderingKind degradeCallPartialOrderingKind(PartialOrderingKind POK)
When propagating a partial ordering kind into a NonCall context, this is used to downgrade a 'Call' i...
static bool hasSameExtendedValue(llvm::APSInt X, llvm::APSInt Y)
Compare two APSInts, extending and switching the sign as necessary to compare their values regardless...
static TemplateLikeDecl * getMoreSpecialized(Sema &S, QualType T1, QualType T2, TemplateLikeDecl *P1, PrimaryDel *P2, TemplateDeductionInfo &Info)
Returns the more specialized template specialization between T1/P1 and T2/P2.
static DeducedTemplateArgument checkDeducedTemplateArguments(ASTContext &Context, const DeducedTemplateArgument &X, const DeducedTemplateArgument &Y, bool AggregateCandidateDeduction=false)
Verify that the given, deduced template arguments are compatible.
static bool isSameDeclaration(Decl *X, Decl *Y)
Determine whether two declaration pointers refer to the same declaration.
static 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 ConvertDeducedTemplateArguments(Sema &S, TemplateDeclT *Template, bool IsDeduced, SmallVectorImpl< DeducedTemplateArgument > &Deduced, TemplateDeductionInfo &Info, Sema::CheckTemplateArgumentInfo &CTAI, LocalInstantiationScope *CurrentInstantiationScope, unsigned NumAlreadyConverted, bool *IsIncomplete)
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 TemplateDeductionResult DeduceNullPtrTemplateArgument(Sema &S, TemplateParameterList *TemplateParams, const NonTypeTemplateParmDecl *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 void MarkUsedTemplateParameters(ASTContext &Ctx, const TemplateArgument &TemplateArg, bool OnlyDeduced, unsigned Depth, llvm::SmallBitVector &Used)
Mark the template parameters that are used by this template argument.
static QualType GetTypeOfFunction(Sema &S, const OverloadExpr::FindResult &R, FunctionDecl *Fn)
Gets the type of a function for template-argument-deducton purposes when it's considered as part of a...
static TemplateDeductionResult CheckDeducedArgumentConstraints(Sema &S, TemplateDeclT *Template, ArrayRef< TemplateArgument > SugaredDeducedArgs, ArrayRef< TemplateArgument > CanonicalDeducedArgs, TemplateDeductionInfo &Info)
static const NonTypeTemplateParmDecl * getDeducedParameterFromExpr(const Expr *E, unsigned Depth)
If the given expression is of a form that permits the deduction of a non-type template parameter,...
static TemplateDeductionResult DeduceNonTypeTemplateArgument(Sema &S, TemplateParameterList *TemplateParams, const NonTypeTemplateParmDecl *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 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....
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 unsigned getPackIndexForParam(Sema &S, FunctionTemplateDecl *FunctionTemplate, const MultiLevelTemplateArgumentList &Args, unsigned ParamIdx)
Find the pack index for a particular parameter index in an instantiation of a function template with ...
static bool AdjustFunctionParmAndArgTypesForDeduction(Sema &S, TemplateParameterList *TemplateParams, unsigned FirstInnerIndex, QualType &ParamType, QualType &ArgType, Expr::Classification ArgClassification, Expr *Arg, unsigned &TDF, TemplateSpecCandidateSet *FailedTSC=nullptr)
Perform the adjustments to the parameter and argument types described in C++ [temp....
static TemplateDeductionResult DeduceTemplateArgumentsFromCallArgument(Sema &S, TemplateParameterList *TemplateParams, unsigned FirstInnerIndex, QualType ParamType, QualType ArgType, Expr::Classification ArgClassification, Expr *Arg, TemplateDeductionInfo &Info, SmallVectorImpl< DeducedTemplateArgument > &Deduced, SmallVectorImpl< Sema::OriginalCallArg > &OriginalCallArgs, bool DecomposedParam, unsigned ArgIdx, unsigned TDF, TemplateSpecCandidateSet *FailedTSC=nullptr)
Perform template argument deduction per [temp.deduct.call] for a single parameter / argument pair.
static 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 bool DeducedArgsNeedReplacement(TemplateDeclT *Template)
static TemplateDeductionResult CheckDeductionConsistency(Sema &S, FunctionTemplateDecl *FTD, int ArgIdx, QualType P, QualType A, ArrayRef< TemplateArgument > DeducedArgs, bool CheckConsistency)
static QualType ResolveOverloadForDeduction(Sema &S, TemplateParameterList *TemplateParams, Expr *Arg, QualType ParamType, bool ParamWasReference, TemplateSpecCandidateSet *FailedTSC=nullptr)
Apply the deduction rules for overload sets.
static bool IsPossiblyOpaquelyQualifiedType(QualType T)
Determines whether the given type is an opaque type that might be more qualified when instantiated.
static const TemplateSpecializationType * getLastTemplateSpecType(QualType QT)
Deduce the template arguments by comparing the template parameter type (which is a template-id) with ...
static std::enable_if_t< IsPartialSpecialization< T >::value, TemplateDeductionResult > FinishTemplateArgumentDeduction(Sema &S, T *Partial, bool IsPartialOrdering, ArrayRef< TemplateArgument > TemplateArgs, SmallVectorImpl< DeducedTemplateArgument > &Deduced, TemplateDeductionInfo &Info)
Complete template argument deduction for a partial specialization.
static TemplateDeductionResult instantiateExplicitSpecifierDeferred(Sema &S, FunctionDecl *Specialization, const MultiLevelTemplateArgumentList &SubstArgs, TemplateDeductionInfo &Info, FunctionTemplateDecl *FunctionTemplate, ArrayRef< TemplateArgument > DeducedArgs)
static bool CheckDeducedPlaceholderConstraints(Sema &S, const AutoType &Type, AutoTypeLoc TypeLoc, QualType Deduced)
static bool IsPossiblyOpaquelyQualifiedTypeInternal(const Type *T)
static bool hasDeducibleTemplateParameters(Sema &S, FunctionTemplateDecl *FunctionTemplate, QualType T)
static bool isForwardingReference(QualType Param, unsigned FirstInnerIndex)
Determine whether a type denotes a forwarding reference.
bool DeducedArgsNeedReplacement< VarTemplatePartialSpecializationDecl >(VarTemplatePartialSpecializationDecl *Spec)
bool DeducedArgsNeedReplacement< ClassTemplatePartialSpecializationDecl >(ClassTemplatePartialSpecializationDecl *Spec)
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::TypeLoc interface and its subclasses.
Allows QualTypes to be sorted and hence used in maps and sets.
C Language Family Type Representation.
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
const ConstantArrayType * getAsConstantArrayType(QualType T) const
QualType getRValueReferenceType(QualType T) const
Return the uniqued reference to the type for an rvalue reference to the specified type.
unsigned getIntWidth(QualType T) const
QualType getBlockPointerType(QualType T) const
Return the uniqued reference to the type for a block of the specified type.
TemplateArgument getCanonicalTemplateArgument(const TemplateArgument &Arg) const
Retrieve the "canonical" template argument.
QualType getMemberPointerType(QualType T, const Type *Cls) const
Return the uniqued reference to the type for a member pointer to the specified type in the specified ...
QualType getTemplateSpecializationType(TemplateName T, ArrayRef< TemplateArgument > Args, QualType Canon=QualType()) const
CanQualType getCanonicalType(QualType T) const
Return the canonical (structural) type corresponding to the specified potentially non-canonical type ...
bool hasSameType(QualType T1, QualType T2) const
Determine whether the given types T1 and T2 are equivalent.
TemplateName getQualifiedTemplateName(NestedNameSpecifier *NNS, bool TemplateKeyword, TemplateName Template) const
Retrieve the template name that represents a qualified template name such as std::vector.
TemplateName getCanonicalTemplateName(TemplateName Name, bool IgnoreDeduced=false) const
Retrieves the "canonical" template name that refers to a given template.
QualType getPointerType(QualType T) const
Return the uniqued reference to the type for a pointer to the specified type.
const IncompleteArrayType * getAsIncompleteArrayType(QualType T) const
bool hasSameFunctionTypeIgnoringExceptionSpec(QualType T, QualType U) const
Determine whether two function types are the same, ignoring exception specifications in cases where t...
QualType getLValueReferenceType(QualType T, bool SpelledAsLValue=true) const
Return the uniqued reference to the type for an lvalue reference to the specified type.
QualType getTypeDeclType(const TypeDecl *Decl, const TypeDecl *PrevDecl=nullptr) const
Return the unique reference to the type for the specified type declaration.
const LangOptions & getLangOpts() const
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,...
CanQualType getSizeType() const
Return the unique type for "size_t" (C99 7.17), defined in <stddef.h>.
QualType removeAddrSpaceQualType(QualType T) const
Remove any existing address space on the type and returns the type with qualifiers intact (or that's ...
QualType getQualifiedType(SplitQualType split) const
Un-split a SplitQualType.
LangAS getDefaultOpenCLPointeeAddrSpace()
Returns default address space based on OpenCL version and enabled features.
bool hasSameUnqualifiedType(QualType T1, QualType T2) const
Determine whether the given types are equivalent after cvr-qualifiers have been removed.
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 getCommonSugaredType(QualType X, QualType Y, bool Unqualified=false)
QualType getArrayDecayedType(QualType T) const
Return the properly qualified result of decaying the specified array type to a pointer.
QualType getFunctionType(QualType ResultTy, ArrayRef< QualType > Args, const FunctionProtoType::ExtProtoInfo &EPI) const
Return a normal function type with a typed argument list.
QualType getAdjustedParameterType(QualType T) const
Perform adjustment on the parameter type of a function.
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...
void adjustDeducedFunctionResultType(FunctionDecl *FD, QualType ResultType)
Change the result type of a function type once it is deduced.
QualType getUnqualifiedArrayType(QualType T, Qualifiers &Quals) const
Return this type as a completely-unqualified array type, capturing the qualifiers in Quals.
TemplateName getDeducedTemplateName(TemplateName Underlying, DefaultArguments DefaultArgs) const
Represents a TemplateName which had some of its default arguments deduced.
const DependentSizedArrayType * getAsDependentSizedArrayType(QualType T) const
The result of parsing/analyzing an expression, statement etc.
Represents a C++11 auto or C++14 decltype(auto) type, possibly constrained by a type-constraint.
ArrayRef< TemplateArgument > getTypeConstraintArguments() const
bool isDecltypeAuto() const
ConceptDecl * getTypeConstraintConcept() const
AutoTypeKeyword getKeyword() const
bool isConstrained() const
A fixed int type of a specified bitwidth.
Represents a C++ conversion function within a class.
QualType getConversionType() const
Returns the type that this conversion function is converting to.
Represents a static or instance method of a struct/union/class.
bool isExplicitObjectMemberFunction() const
[C++2b][dcl.fct]/p7 An explicit object member function is a non-static member function with an explic...
RefQualifierKind getRefQualifier() const
Retrieve the ref-qualifier associated with this method.
Qualifiers getMethodQualifiers() const
The null pointer literal (C++11 [lex.nullptr])
Represents a C++ struct/union/class.
CXXMethodDecl * getLambdaCallOperator() const
Retrieve the lambda call operator of the closure type if this is a closure type.
Declaration of a class template.
QualType getInjectedClassNameSpecialization()
Retrieve the template specialization type of the injected-class-name for this class template.
QualType getInjectedSpecializationType() const
Retrieves the injected specialization type for this partial specialization.
ClassTemplateDecl * getSpecializedTemplate() const
Retrieve the template that this specialization specializes.
bool isClassScopeExplicitSpecialization() const
Is this an explicit specialization at class scope (within the class that owns the primary template)?...
Complex values, per C99 6.2.5p11.
Declaration of a C++20 concept.
const TypeClass * getTypePtr() const
Represents a concrete matrix type with constant number of rows and columns.
unsigned getNumColumns() const
Returns the number of columns in the matrix.
unsigned getNumRows() const
Returns the number of rows in the matrix.
The result of a constraint satisfaction check, containing the necessary information to diagnose an un...
A POD class for pairing a NamedDecl* with an access specifier.
DeclContext - This is used only as base class of specific decl types that can act as declaration cont...
DeclContext * getParent()
getParent - Returns the containing DeclContext.
A reference to a declared variable, function, enum, etc.
Decl - This represents one declaration (or definition), e.g.
TemplateDecl * getDescribedTemplate() const
If this is a declaration that describes some template, this method returns that template declaration.
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.
virtual SourceRange getSourceRange() const LLVM_READONLY
Source range that this declaration covers.
Captures a template argument whose value has been deduced via c++ template argument deduction.
void setDeducedFromArrayBound(bool Deduced)
Specify whether the given non-type template argument was deduced from an array bound.
bool wasDeducedFromArrayBound() const
For a non-type template argument, determine whether the template argument was deduced from an array b...
TemplateName getTemplateName() const
Retrieve the name of the template that we are deducing.
Common base class for placeholders for types that get replaced by placeholder type deduction: C++11 a...
Represents an extended address space qualifier where the input address space value is dependent.
Expr * getAddrSpaceExpr() const
QualType getPointeeType() const
Represents an extended vector type where either the type or size is dependent.
Expr * getSizeExpr() const
QualType getElementType() const
Represents a matrix type where the type and the number of rows and columns is dependent on a template...
Expr * getColumnExpr() const
Expr * getRowExpr() const
Represents a dependent template name that cannot be resolved prior to template instantiation.
Represents a template specialization type whose template cannot be resolved, e.g.
ArrayRef< TemplateArgument > template_arguments() const
NestedNameSpecifier * getQualifier() const
Represents a vector type where either the type or size is dependent.
Recursive AST visitor that supports extension via dynamic dispatch.
virtual bool TraverseTemplateName(TemplateName Template)
Recursively visit a template name and dispatch to the appropriate method.
Represents a type that was referred to using an elaborated type keyword, e.g., struct S,...
RAII object that enters a new expression evaluation context.
Store information needed for an explicit specifier.
bool isInvalid() const
Determine if the explicit specifier is invalid.
const Expr * getExpr() const
The return type of classify().
This represents one expression.
bool isValueDependent() const
Determines whether the value of this expression depends on.
SourceLocation getExprLoc() const LLVM_READONLY
getExprLoc - Return the preferred location for the arrow when diagnosing a problem with a generic exp...
std::optional< llvm::APSInt > getIntegerConstantExpr(const ASTContext &Ctx, SourceLocation *Loc=nullptr) const
isIntegerConstantExpr - Return the value if this expression is a valid integer constant expression.
Classification Classify(ASTContext &Ctx) const
Classify - Classify this expression according to the C++11 expression taxonomy.
ExtVectorType - Extended vector type.
Stores a list of template parameters and the associated requires-clause (if any) for a TemplateDecl a...
Represents a function declaration or definition.
const ParmVarDecl * getParamDecl(unsigned i) const
bool isFunctionTemplateSpecialization() const
Determine whether this function is a function template specialization.
FunctionTemplateDecl * getDescribedFunctionTemplate() const
Retrieves the function template that is described by this function declaration.
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...
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.
void getAssociatedConstraints(SmallVectorImpl< const Expr * > &AC) const
Get the associated-constraints of this function declaration.
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)
const TypeClass * getTypePtr() const
Describes an C or C++ initializer list.
unsigned getNumInits() const
ArrayRef< Expr * > inits()
The injected class name of a C++ class template or class template partial specialization.
An lvalue reference type, per C++11 [dcl.ref].
A C++ lambda expression, which produces a function object (of unspecified type) that can be invoked l...
A stack-allocated class that identifies which local variable declaration instantiations are present i...
void SetPartiallySubstitutedPack(NamedDecl *Pack, const TemplateArgument *ExplicitArgs, unsigned NumExplicitArgs)
Note that the given parameter pack has been partially substituted via explicit specification of templ...
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.
QualType getPointeeType() const
const Type * getClass() const
Data structure that captures multiple levels of template argument lists for use in template instantia...
void replaceInnermostTemplateArguments(Decl *AssociatedDecl, ArgList Args)
Replaces the current 'innermost' level with the provided argument list.
This represents a decl that may have a name.
DeclarationName getDeclName() const
Get the actual, stored name of the declaration, which may be a special name.
Class that aids in the construction of nested-name-specifiers along with source-location information ...
Represents a C++ nested name specifier, such as "\::std::vector<int>::".
NestedNameSpecifier * getPrefix() const
Return the prefix of this nested name specifier.
const Type * getAsType() const
Retrieve the type stored in this nested name specifier.
NonTypeTemplateParmDecl - Declares a non-type template parameter, e.g., "Size" in.
bool isExpandedParameterPack() const
Whether this parameter is a non-type template parameter pack that has a known list of different types...
unsigned getIndex() const
Get the index of the template parameter within its parameter list.
unsigned getDepth() const
Get the nesting depth of the template parameter.
Represents a pointer to an Objective C object.
A reference to an overloaded function set, either an UnresolvedLookupExpr or an UnresolvedMemberExpr.
bool hasExplicitTemplateArgs() const
Determines whether this expression had explicit template arguments.
static FindResult find(Expr *E)
Finds the overloaded expression in the given expression E of OverloadTy.
SourceLocation getNameLoc() const
Gets the location of the name.
decls_iterator decls_begin() const
void copyTemplateArgumentsInto(TemplateArgumentListInfo &List) const
Copies the template arguments into the given structure.
decls_iterator decls_end() const
Represents a C++11 pack expansion that produces a sequence of expressions.
Represents a pack expansion of types.
QualType getPattern() const
Retrieve the pattern of this pack expansion, which is the type that will be repeatedly instantiated w...
std::optional< unsigned > getNumExpansions() const
Retrieve the number of expansions that this pack expansion will generate, if known.
bool hasSelectedType() const
QualType getSelectedType() const
A single parameter index whose accessors require each use to make explicit the parameter index encodi...
PointerType - C99 6.7.5.1 - Pointer Declarators.
QualType getPointeeType() const
A (possibly-)qualified type.
bool hasQualifiers() const
Determine whether this type has any qualifiers.
bool isNull() const
Return true if this QualType doesn't point to a type yet.
const Type * getTypePtr() const
Retrieves a pointer to the underlying (unqualified) type.
LangAS getAddressSpace() const
Return the address space of this type.
Qualifiers getQualifiers() const
Retrieve the set of qualifiers applied to this type.
QualType getNonReferenceType() const
If Type is a reference type (e.g., const int&), returns the type that the reference refers to ("const...
QualType getCanonicalType() const
QualType getUnqualifiedType() const
Retrieve the unqualified variant of the given type, removing as little sugar as possible.
bool hasAddressSpace() const
Check if this type has any address space qualifier.
unsigned getCVRQualifiers() const
Retrieve the set of CVR (const-volatile-restrict) qualifiers applied to this type.
Represents a template name as written in source code.
The collection of all-type qualifiers we support.
unsigned getCVRQualifiers() const
void removeCVRQualifiers(unsigned mask)
@ OCL_Strong
Assigning into this object requires the old value to be released and the new value to be retained.
@ OCL_ExplicitNone
This object can be modified without requiring retains or releases.
@ OCL_None
There is no lifetime qualification on this type.
void removeObjCLifetime()
bool isStrictSupersetOf(Qualifiers Other) const
Determine whether this set of qualifiers is a strict superset of another set of qualifiers,...
bool hasNonTrivialObjCLifetime() const
True if the lifetime is neither None or ExplicitNone.
bool 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].
A helper class that allows the use of isa/cast/dyncast to detect TagType objects of structs/unions/cl...
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 CheckInstantiatedFunctionTemplateConstraints(SourceLocation PointOfInstantiation, FunctionDecl *Decl, ArrayRef< TemplateArgument > TemplateArgs, ConstraintSatisfaction &Satisfaction)
QualType SubstAutoType(QualType TypeWithAuto, QualType Replacement)
Substitute Replacement for auto in TypeWithAuto.
LocalInstantiationScope * CurrentInstantiationScope
The current instantiation scope used to store local variables.
TemplateArgumentLoc getTrivialTemplateArgumentLoc(const TemplateArgument &Arg, QualType NTTPType, SourceLocation Loc, NamedDecl *TemplateParam=nullptr)
Allocate a TemplateArgumentLoc where all locations have been initialized to the given location.
TemplateDeductionResult DeduceTemplateArgumentsFromType(TemplateDecl *TD, QualType FromType, sema::TemplateDeductionInfo &Info)
Deduce the template arguments of the given template from FromType.
QualType ReplaceAutoType(QualType TypeWithAuto, QualType Replacement)
Completely replace the auto in TypeWithAuto by Replacement.
bool TemplateParameterListsAreEqual(const TemplateCompareNewDeclInfo &NewInstFrom, TemplateParameterList *New, const NamedDecl *OldInstFrom, TemplateParameterList *Old, bool Complain, TemplateParameterListEqualKind Kind, SourceLocation TemplateArgLoc=SourceLocation())
Determine whether the given template parameter lists are equivalent.
TemplateArgumentLoc SubstDefaultTemplateArgumentIfAvailable(TemplateDecl *Template, SourceLocation TemplateLoc, SourceLocation RAngleLoc, Decl *Param, ArrayRef< TemplateArgument > SugaredConverted, ArrayRef< TemplateArgument > CanonicalConverted, bool &HasDefaultArg)
If the given template parameter has a default template argument, substitute into that default templat...
ClassTemplatePartialSpecializationDecl * getMoreSpecializedPartialSpecialization(ClassTemplatePartialSpecializationDecl *PS1, ClassTemplatePartialSpecializationDecl *PS2, SourceLocation Loc)
Returns the more specialized class template partial specialization according to the rules of partial ...
FunctionDecl * getMoreConstrainedFunction(FunctionDecl *FD1, FunctionDecl *FD2)
Returns the more constrained function according to the rules of partial ordering by constraints (C++ ...
FunctionDecl * InstantiateFunctionDeclaration(FunctionTemplateDecl *FTD, const TemplateArgumentList *Args, SourceLocation Loc, CodeSynthesisContext::SynthesisKind CSC=CodeSynthesisContext::ExplicitTemplateArgumentSubstitution)
Instantiate (or find existing instantiation of) a function template with a given set of template argu...
QualType BuildStdInitializerList(QualType Element, SourceLocation Loc)
Looks for the std::initializer_list template and instantiates it with Element, or emits an error if i...
ExpressionEvaluationContextRecord & parentEvaluationContext()
bool isTemplateTemplateParameterAtLeastAsSpecializedAs(TemplateParameterList *PParam, TemplateDecl *PArg, TemplateDecl *AArg, const DefaultArguments &DefaultArgs, SourceLocation ArgLoc, bool PartialOrdering, bool *MatchedPackOnParmToNonPackOnArg)
@ CTAK_DeducedFromArrayBound
The template argument was deduced from an array bound via template argument deduction.
@ CTAK_Specified
The template argument was specified in the code or was instantiated with some deduced template argume...
@ CTAK_Deduced
The template argument was deduced via template argument deduction.
bool DeduceReturnType(FunctionDecl *FD, SourceLocation Loc, bool Diagnose=true)
bool IsQualificationConversion(QualType FromType, QualType ToType, bool CStyle, bool &ObjCLifetimeConversion)
IsQualificationConversion - Determines whether the conversion from an rvalue of type FromType to ToTy...
QualType BuildFunctionType(QualType T, MutableArrayRef< QualType > ParamTypes, SourceLocation Loc, DeclarationName Entity, const FunctionProtoType::ExtProtoInfo &EPI)
Build a function type.
ExprResult BuildExpressionFromNonTypeTemplateArgument(const TemplateArgument &Arg, SourceLocation Loc)
ASTContext & getASTContext() const
UnresolvedSetIterator getMostSpecialized(UnresolvedSetIterator SBegin, UnresolvedSetIterator SEnd, TemplateSpecCandidateSet &FailedCandidates, SourceLocation Loc, const PartialDiagnostic &NoneDiag, const PartialDiagnostic &AmbigDiag, const PartialDiagnostic &CandidateDiag, bool Complain=true, QualType TargetType=QualType())
Retrieve the most specialized of the given function template specializations.
TypeSourceInfo * SubstType(TypeSourceInfo *T, const MultiLevelTemplateArgumentList &TemplateArgs, SourceLocation Loc, DeclarationName Entity, bool AllowDeducedTST=false)
Perform substitution on the type T with a given set of template arguments.
ExprResult ImpCastExprToType(Expr *E, QualType Type, CastKind CK, ExprValueKind VK=VK_PRValue, const CXXCastPath *BasePath=nullptr, CheckedConversionKind CCK=CheckedConversionKind::Implicit)
ImpCastExprToType - If Expr is not of type 'Type', insert an implicit cast.
FunctionDecl * ResolveSingleFunctionTemplateSpecialization(OverloadExpr *ovl, bool Complain=false, DeclAccessPair *Found=nullptr, TemplateSpecCandidateSet *FailedTSC=nullptr)
Given an expression that refers to an overloaded function, try to resolve that overloaded function ex...
PrintingPolicy getPrintingPolicy() const
Retrieve a suitable printing policy for diagnostics.
bool SubstTemplateArguments(ArrayRef< TemplateArgumentLoc > Args, const MultiLevelTemplateArgumentList &TemplateArgs, TemplateArgumentListInfo &Outputs)
@ TPL_TemplateParamsEquivalent
We are determining whether the template-parameters are equivalent according to C++ [temp....
bool 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
void collectUnexpandedParameterPacks(TemplateArgument Arg, SmallVectorImpl< UnexpandedParameterPack > &Unexpanded)
Collect the set of unexpanded parameter packs within the given template argument.
bool CheckConstraintSatisfaction(const NamedDecl *Template, ArrayRef< const Expr * > ConstraintExprs, const MultiLevelTemplateArgumentList &TemplateArgLists, SourceRange TemplateIDRange, ConstraintSatisfaction &Satisfaction)
Check whether the given list of constraint expressions are satisfied (as if in a 'conjunction') given...
FunctionTemplateDecl * getMoreSpecializedTemplate(FunctionTemplateDecl *FT1, FunctionTemplateDecl *FT2, SourceLocation Loc, TemplatePartialOrderingContext TPOC, unsigned NumCallArguments1, QualType RawObj1Ty={}, QualType RawObj2Ty={}, bool Reversed=false)
Returns the more specialized function template according to the rules of function template partial or...
std::optional< unsigned > getNumArgumentsInExpansion(QualType T, const MultiLevelTemplateArgumentList &TemplateArgs)
Determine the number of arguments in the given pack expansion type.
TemplateDeductionResult FinishTemplateArgumentDeduction(FunctionTemplateDecl *FunctionTemplate, SmallVectorImpl< DeducedTemplateArgument > &Deduced, unsigned NumExplicitlySpecified, FunctionDecl *&Specialization, sema::TemplateDeductionInfo &Info, SmallVectorImpl< OriginalCallArg > const *OriginalCallArgs, bool PartialOverloading, bool PartialOrdering, llvm::function_ref< bool()> CheckNonDependent=[] { return false;})
Finish template argument deduction for a function template, checking the deduced template arguments f...
ExplicitSpecifier instantiateExplicitSpecifier(const MultiLevelTemplateArgumentList &TemplateArgs, ExplicitSpecifier ES)
TemplateDeductionResult SubstituteExplicitTemplateArguments(FunctionTemplateDecl *FunctionTemplate, TemplateArgumentListInfo &ExplicitTemplateArgs, SmallVectorImpl< DeducedTemplateArgument > &Deduced, SmallVectorImpl< QualType > &ParamTypes, QualType *FunctionType, sema::TemplateDeductionInfo &Info)
Substitute the explicitly-provided template arguments into the given function template according to C...
bool SubstParmTypes(SourceLocation Loc, ArrayRef< ParmVarDecl * > Params, const FunctionProtoType::ExtParameterInfo *ExtParamInfos, const MultiLevelTemplateArgumentList &TemplateArgs, SmallVectorImpl< QualType > &ParamTypes, SmallVectorImpl< ParmVarDecl * > *OutParams, ExtParameterInfoBuilder &ParamInfos)
Substitute the given template arguments into the given set of parameters, producing the set of parame...
FunctionDecl * resolveAddressOfSingleOverloadCandidate(Expr *E, DeclAccessPair &FoundResult)
Given an expression that refers to an overloaded function, try to resolve that function to a single f...
DeclContext * CurContext
CurContext - This is the current declaration context of parsing.
MultiLevelTemplateArgumentList getTemplateInstantiationArgs(const NamedDecl *D, const DeclContext *DC=nullptr, bool Final=false, std::optional< ArrayRef< TemplateArgument > > Innermost=std::nullopt, bool RelativeToPrimary=false, const FunctionDecl *Pattern=nullptr, bool ForConstraintInstantiation=false, bool SkipForSpecialization=false, bool ForDefaultArgumentSubstitution=false)
Retrieve the template argument list(s) that should be used to instantiate the definition of the given...
SuppressedDiagnosticsMap SuppressedDiagnostics
QualType getDecltypeForExpr(Expr *E)
getDecltypeForExpr - Given an expr, will return the decltype for that expression, according to the ru...
ExprResult CheckPlaceholderExpr(Expr *E)
Check for operands with placeholder types and complain if found.
Decl * SubstDecl(Decl *D, DeclContext *Owner, const MultiLevelTemplateArgumentList &TemplateArgs)
TypeSourceInfo * SubstAutoTypeSourceInfoDependent(TypeSourceInfo *TypeWithAuto)
bool IsAtLeastAsConstrained(NamedDecl *D1, MutableArrayRef< const Expr * > AC1, NamedDecl *D2, MutableArrayRef< const Expr * > AC2, bool &Result)
Check whether the given declaration's associated constraints are at least as constrained than another...
TypeSourceInfo * ReplaceAutoTypeSourceInfo(TypeSourceInfo *TypeWithAuto, QualType Replacement)
bool isCompleteType(SourceLocation Loc, QualType T, CompleteTypeKind Kind=CompleteTypeKind::Default)
bool isStdInitializerList(QualType Ty, QualType *Element)
Tests whether Ty is an instance of std::initializer_list and, if it is and Element is not NULL,...
void InstantiateFunctionDefinition(SourceLocation PointOfInstantiation, FunctionDecl *Function, bool Recursive=false, bool DefinitionRequired=false, bool AtEndOfTU=false)
Instantiate the definition of the given function from its template.
void MarkUsedTemplateParameters(const Expr *E, bool OnlyDeduced, unsigned Depth, llvm::SmallBitVector &Used)
Mark which template parameters are used in a given expression.
@ Unevaluated
The current expression and its subexpressions occur within an unevaluated operand (C++11 [expr]p7),...
QualType getLambdaConversionFunctionResultType(const FunctionProtoType *CallOpType, CallingConv CC)
Get the return type to use for a lambda's conversion function(s) to function pointer type,...
QualType getCompletedType(Expr *E)
Get the type of expression E, triggering instantiation to complete the type if necessary – that is,...
TypeSourceInfo * SubstAutoTypeSourceInfo(TypeSourceInfo *TypeWithAuto, QualType Replacement)
Substitute Replacement for auto in TypeWithAuto.
void DiagnoseAutoDeductionFailure(const VarDecl *VDecl, const Expr *Init)
TemplateArgumentLoc getIdentityTemplateArgumentLoc(NamedDecl *Param, SourceLocation Location)
Get a template argument mapping the given template parameter to itself, e.g.
bool CheckIfFunctionSpecializationIsImmediate(FunctionDecl *FD, SourceLocation Loc)
QualType SubstAutoTypeDependent(QualType TypeWithAuto)
TemplateDeductionResult DeduceTemplateArguments(ClassTemplatePartialSpecializationDecl *Partial, ArrayRef< TemplateArgument > TemplateArgs, sema::TemplateDeductionInfo &Info)
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.
bool IsDerivedFrom(SourceLocation Loc, QualType Derived, QualType Base)
Determine whether the type Derived is a C++ class that is derived from the type Base.
@ Diagnose
Diagnose issues that are non-constant or that are extensions.
ExprResult BuildExpressionFromDeclTemplateArgument(const TemplateArgument &Arg, QualType ParamType, SourceLocation Loc, NamedDecl *TemplateParam=nullptr)
Given a non-type template argument that refers to a declaration and the type of its corresponding non...
TemplateDeductionResult DeduceAutoType(TypeLoc AutoTypeLoc, Expr *Initializer, QualType &Result, sema::TemplateDeductionInfo &Info, bool DependentDeduction=false, bool IgnoreConstraints=false, TemplateSpecCandidateSet *FailedTSC=nullptr)
Deduce the type for an auto type-specifier (C++11 [dcl.spec.auto]p6)
QualType adjustCCAndNoReturn(QualType ArgFunctionType, QualType FunctionType, bool AdjustExceptionSpec=false)
Adjust the type ArgFunctionType to match the calling convention, noreturn, and optionally the excepti...
void HandleFunctionTypeMismatch(PartialDiagnostic &PDiag, QualType FromType, QualType ToType)
HandleFunctionTypeMismatch - Gives diagnostic information for differeing function types.
bool IsFunctionConversion(QualType FromType, QualType ToType, QualType &ResultTy)
Determine whether the conversion from FromType to ToType is a valid conversion that strips "noexcept"...
void MarkDeducedTemplateParameters(const FunctionTemplateDecl *FunctionTemplate, llvm::SmallBitVector &Deduced)
Encodes a location in the source.
A trivial tuple used to represent a source range.
SourceLocation getEnd() const
void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Context, bool Canonical, bool ProfileLambdaExpr=false) const
Produce a unique representation of the given statement.
Represents the result of substituting a set of types for a template type parameter pack.
TemplateArgument getArgumentPack() const
unsigned getIndex() const
Returns the index of the replaced parameter in the associated declaration.
const TemplateTypeParmDecl * getReplacedParameter() const
Gets the template parameter declaration that was substituted for.
A convenient class for passing around template argument information.
void addArgument(const TemplateArgumentLoc &Loc)
A template argument list.
static TemplateArgumentList * CreateCopy(ASTContext &Context, ArrayRef< TemplateArgument > Args)
Create a new template argument list that copies the given set of template arguments.
unsigned size() const
Retrieve the number of template arguments in this template argument list.
const TemplateArgument & get(unsigned Idx) const
Retrieve the template argument at a given index.
ArrayRef< TemplateArgument > asArray() const
Produce this as an array ref.
Location wrapper for a TemplateArgument.
const TemplateArgument & getArgument() const
Represents a template argument.
QualType getParamTypeForDecl() const
Expr * getAsExpr() const
Retrieve the template argument as an expression.
pack_iterator pack_end() const
Iterator referencing one past the last argument of a template argument pack.
pack_iterator pack_begin() const
Iterator referencing the first argument of a template argument pack.
QualType getNonTypeTemplateArgumentType() const
If this is a non-type template argument, get its type.
void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Context) const
Used to insert TemplateArguments into FoldingSets.
QualType getAsType() const
Retrieve the type for a type template argument.
llvm::APSInt getAsIntegral() const
Retrieve the template argument as an integral value.
QualType getNullPtrType() const
Retrieve the type for null non-type template argument.
static TemplateArgument CreatePackCopy(ASTContext &Context, ArrayRef< TemplateArgument > Args)
Create a new template argument pack by copying the given set of template arguments.
TemplateName getAsTemplate() const
Retrieve the template name for a template name argument.
TemplateArgument getPackExpansionPattern() const
When the template argument is a pack expansion, returns the pattern of the pack expansion.
bool isNull() const
Determine whether this template argument has no value.
static TemplateArgument getEmptyPack()
unsigned pack_size() const
The number of template arguments in the given template argument pack.
bool structurallyEquals(const TemplateArgument &Other) const
Determines whether two template arguments are superficially the same.
ValueDecl * getAsDecl() const
Retrieve the declaration for a declaration non-type template argument.
ArrayRef< TemplateArgument > pack_elements() const
Iterator range referencing all of the elements of a template argument pack.
@ Declaration
The template argument is a declaration that was provided for a pointer, reference,...
@ Template
The template argument is a template name that was provided for a template template parameter.
@ StructuralValue
The template argument is a non-type template argument that can't be represented by the special-case D...
@ Pack
The template argument is actually a parameter pack.
@ TemplateExpansion
The template argument is a pack expansion of a template name that was provided for a template templat...
@ NullPtr
The template argument is a null pointer or null pointer to member that was provided for a non-type te...
@ Type
The template argument is a type.
@ Null
Represents an empty template argument, e.g., one that has not been deduced.
@ Integral
The template argument is an integral value stored in an llvm::APSInt that was provided for an integra...
@ Expression
The template argument is an expression, and we've not resolved it to one of the other forms yet,...
ArgKind getKind() const
Return the kind of stored template argument.
bool isPackExpansion() const
Determine whether this template argument is a pack expansion.
TemplateName getAsTemplateOrTemplatePattern() const
Retrieve the template argument as a template name; if the argument is a pack expansion,...
The base class of all kinds of template declarations (e.g., class, function, etc.).
SourceRange getSourceRange() const override LLVM_READONLY
Source range that this declaration covers.
void getAssociatedConstraints(llvm::SmallVectorImpl< const Expr * > &AC) const
Get the total constraint-expression associated with this template, including constraint-expressions d...
TemplateParameterList * getTemplateParameters() const
Get the list of template parameters.
Represents a C++ template name within the type system.
TemplateDecl * getAsTemplateDecl(bool IgnoreDeduced=false) const
Retrieve the underlying template declaration that this template name refers to, if known.
DependentTemplateName * getAsDependentTemplateName() const
Retrieve the underlying dependent template name structure, if any.
QualifiedTemplateName * getAsQualifiedTemplateName() const
Retrieve the underlying qualified template name structure, if any.
void * getAsVoidPointer() const
Retrieve the template name as a void pointer.
Stores a list of template parameters for a TemplateDecl and its derived classes.
NamedDecl * getParam(unsigned Idx)
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.
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.
Declaration of a template type parameter.
static TemplateTypeParmDecl * Create(const ASTContext &C, DeclContext *DC, SourceLocation KeyLoc, SourceLocation NameLoc, unsigned D, unsigned P, IdentifierInfo *Id, bool Typename, bool ParameterPack, bool HasTypeConstraint=false, std::optional< unsigned > NumExpanded=std::nullopt)
unsigned getDepth() const
Retrieve the depth of the template parameter.
Wrapper for template type parameters.
unsigned getIndex() const
unsigned getDepth() const
const Type * getTypeForDecl() const
TyLocType push(QualType T)
Pushes space for a new TypeLoc of the given type.
void reserve(size_t Requested)
Ensures that this buffer has at least as much capacity as described.
Base wrapper for a particular "section" of type source info.
SourceRange getLocalSourceRange() const
Get the local source range.
unsigned getFullDataSize() const
Returns the size of the type source info data block.
void copy(TypeLoc other)
Copies the other type loc into this one.
A container of type source information.
SourceLocation getNameLoc() const
void setNameLoc(SourceLocation Loc)
The base class of the type hierarchy.
CXXRecordDecl * getAsCXXRecordDecl() const
Retrieves the CXXRecordDecl that this type refers to, either because the type is a RecordType or beca...
bool isIncompleteArrayType() const
bool isPlaceholderType() const
Test for a type which does not represent an actual type-system type but is instead used as a placehol...
bool isRValueReferenceType() const
bool canDecayToPointerType() const
Determines whether this type can decay to a pointer type.
bool isFunctionPointerType() const
bool isPointerType() const
const T * castAs() const
Member-template castAs<specific type>.
bool isReferenceType() const
QualType getPointeeType() const
If this is a pointer, ObjC object pointer, or block pointer, this returns the respective pointee.
AutoType * getContainedAutoType() const
Get the AutoType whose type will be deduced for a variable with an initializer of this type.
bool isLValueReferenceType() const
bool isDependentType() const
Whether this type is a dependent type, meaning that its definition somehow depends on a template para...
QualType getCanonicalTypeInternal() const
bool isMemberPointerType() const
bool isObjCLifetimeType() const
Returns true if objects of this type have lifetime semantics under ARC.
bool isUndeducedType() const
Determine whether this type is an undeduced type, meaning that it somehow involves a C++11 'auto' typ...
bool isFunctionType() const
bool isObjCObjectPointerType() const
bool isMemberFunctionPointerType() const
bool isAnyPointerType() const
TypeClass getTypeClass() const
bool isCanonicalUnqualified() const
Determines if this type would be canonical if it had no further qualification.
const T * getAs() const
Member-template getAs<specific type>'.
bool isRecordType() const
The iterator over UnresolvedSets.
Represent the declaration of a variable (in which case it is an lvalue) a function (in which case it ...
Represents a variable declaration or definition.
bool isInitCapture() const
Whether this variable is the implicit variable for a lambda init-capture.
Declaration of a variable template.
const TemplateArgumentList & getTemplateArgs() const
Retrieve the template arguments of the variable template specialization.
bool isClassScopeExplicitSpecialization() const
VarTemplateDecl * getSpecializedTemplate() const
Retrieve the template that this specialization specializes.
Represents a GCC generic vector type.
Provides information about an attempted template argument deduction, whose success or failure was des...
void setExplicitArgs(TemplateArgumentList *NewDeducedSugared, TemplateArgumentList *NewDeducedCanonical)
Provide an initial template argument list that contains the explicitly-specified arguments.
TemplateArgumentList * takeCanonical()
TemplateArgumentList * takeSugared()
Take ownership of the deduced template argument lists.
SourceLocation getLocation() const
Returns the location at which template argument is occurring.
void clearSFINAEDiagnostic()
Discard any SFINAE diagnostics.
TemplateArgument SecondArg
The second template argument to which the template argument deduction failure refers.
TemplateParameter Param
The template parameter to which a template argument deduction failure refers.
diag_iterator diag_end() const
Returns an iterator at the end of the sequence of suppressed diagnostics.
void reset(TemplateArgumentList *NewDeducedSugared, TemplateArgumentList *NewDeducedCanonical)
Provide a new template argument list that contains the results of template argument deduction.
unsigned getDeducedDepth() const
The depth of template parameters for which deduction is being performed.
diag_iterator diag_begin() const
Returns an iterator at the beginning of the sequence of suppressed diagnostics.
TemplateArgument FirstArg
The first template argument to which the template argument deduction failure refers.
void setMatchedPackOnParmToNonPackOnArg()
ConstraintSatisfaction AssociatedConstraintsSatisfaction
The constraint satisfaction details resulting from the associated constraints satisfaction tests.
bool hasMatchedPackOnParmToNonPackOnArg() const
unsigned CallArgIndex
The index of the function argument that caused a deduction failure.
__inline void unsigned int _2
The JSON file list parser is used to communicate input to InstallAPI.
@ OO_None
Not an overloaded operator.
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)
unsigned toTargetAddressSpace(LangAS AS)
@ 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.
llvm::PointerUnion< TemplateTypeParmDecl *, NonTypeTemplateParmDecl *, TemplateTemplateParmDecl * > TemplateParameter
Stores a template parameter of any kind.
std::optional< unsigned > getExpandedPackSize(const NamedDecl *Param)
Check whether the template parameter is a pack expansion, and if so, determine the number of paramete...
bool isLambdaConversionOperator(CXXConversionDecl *C)
const FunctionProtoType * T
void printTemplateArgumentList(raw_ostream &OS, ArrayRef< TemplateArgument > Args, const PrintingPolicy &Policy, const TemplateParameterList *TPL=nullptr)
Print a template argument list, including the '<' and '>' enclosing the template arguments.
TPOC
The context in which partial ordering of function templates occurs.
@ TPOC_Conversion
Partial ordering of function templates for a call to a conversion function.
@ TPOC_Other
Partial ordering of function templates in other contexts, e.g., taking the address of a function temp...
@ TPOC_Call
Partial ordering of function templates for a function call.
bool declaresSameEntity(const Decl *D1, const Decl *D2)
Determine whether two declarations declare the same entity.
TemplateDeductionResult
Describes the result of template argument deduction.
@ MiscellaneousDeductionFailure
Deduction failed; that's all we know.
@ NonDependentConversionFailure
Checking non-dependent argument conversions failed.
@ ConstraintsNotSatisfied
The deduced arguments did not satisfy the constraints associated with the template.
@ Underqualified
Template argument deduction failed due to inconsistent cv-qualifiers on a template parameter type tha...
@ InstantiationDepth
Template argument deduction exceeded the maximum template instantiation depth (which has already been...
@ InvalidExplicitArguments
The explicitly-specified template arguments were not valid template arguments for the given template.
@ 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.
@ EST_Uninstantiated
not instantiated yet
@ EST_None
no exception specification
TemplateDeductionFlags
Various flags that control template argument deduction.
@ TDF_None
No template argument deduction flags, which indicates the strictest results for template argument ded...
@ TDF_DerivedClass
Within template argument deduction from a function call, we are matching in a case where we can perfo...
@ TDF_TopLevelParameterTypeList
Whether we are performing template argument deduction for parameters and arguments in a top-level tem...
@ TDF_IgnoreQualifiers
Within template argument deduction from a function call, we are matching in a case where we ignore cv...
@ TDF_ParamWithReferenceType
Within template argument deduction from a function call, we are matching with a parameter type for wh...
@ TDF_SkipNonDependent
Allow non-dependent types to differ, e.g., when performing template argument deduction from a functio...
@ TDF_AllowCompatibleFunctionType
Within template argument deduction from overload resolution per C++ [over.over] allow matching functi...
@ TDF_ArgWithReferenceType
Within template argument deduction for a conversion function, we are matching with an argument type f...
ActionResult< CXXBaseSpecifier * > BaseResult
Represents an explicit template argument list in C++, e.g., the "<int>" in "sort<int>".
SourceLocation RAngleLoc
The source location of the right angle bracket ('>').
SourceLocation LAngleLoc
The source location of the left angle bracket ('<').
llvm::ArrayRef< TemplateArgumentLoc > arguments() const
A pack that we're currently deducing.
DeducedPack(unsigned Index)
SmallVector< DeducedTemplateArgument, 4 > New
DeducedTemplateArgument Saved
DeducedTemplateArgument DeferredDeduction
Holds information about the various types of exception specification.
ExceptionSpecificationType Type
The kind of exception specification this is.
Extra information about a function prototype.
const ExtParameterInfo * ExtParameterInfos
FunctionType::ExtInfo ExtInfo
bool HasFormOfMemberPointer
OverloadExpr * Expression
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
bool MatchedPackOnParmToNonPackOnArg
Is set to true when, in the context of TTP matching, a pack parameter matches non-pack arguments.
@ 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.