45#include "llvm/ADT/APInt.h"
46#include "llvm/ADT/APSInt.h"
47#include "llvm/ADT/ArrayRef.h"
48#include "llvm/ADT/DenseMap.h"
49#include "llvm/ADT/FoldingSet.h"
50#include "llvm/ADT/SmallBitVector.h"
51#include "llvm/ADT/SmallPtrSet.h"
52#include "llvm/ADT/SmallVector.h"
53#include "llvm/Support/Casting.h"
54#include "llvm/Support/Compiler.h"
55#include "llvm/Support/ErrorHandling.h"
113using namespace clang;
119 if (Y.getBitWidth() >
X.getBitWidth())
120 X =
X.extend(Y.getBitWidth());
121 else if (Y.getBitWidth() <
X.getBitWidth())
122 Y = Y.extend(
X.getBitWidth());
125 if (
X.isSigned() != Y.isSigned()) {
127 if ((Y.isSigned() && Y.isNegative()) || (
X.isSigned() &&
X.isNegative()))
146 bool *HasDeducedAnyParam);
162 bool OnlyDeduced,
unsigned Depth,
163 llvm::SmallBitVector &
Used);
166 bool OnlyDeduced,
unsigned Level,
167 llvm::SmallBitVector &Deduced);
177 if (
const auto *IC = dyn_cast<ImplicitCastExpr>(
E))
178 E = IC->getSubExpr();
179 else if (
const auto *CE = dyn_cast<ConstantExpr>(
E))
180 E = CE->getSubExpr();
181 else if (
const auto *Subst = dyn_cast<SubstNonTypeTemplateParmExpr>(
E))
182 E = Subst->getReplacement();
183 else if (
const auto *CCE = dyn_cast<CXXConstructExpr>(
E)) {
185 if (CCE->getParenOrBraceRange().isValid())
188 assert(CCE->getNumArgs() >= 1 &&
"implicit construct expr should have 1 arg");
194 if (
const auto *DRE = dyn_cast<DeclRefExpr>(
E))
195 if (
const auto *NTTP = dyn_cast<NonTypeTemplateParmDecl>(DRE->getDecl()))
196 if (NTTP->getDepth() == Depth)
211 X = NX->getUnderlyingDecl();
212 if (
NamedDecl *NY = dyn_cast<NamedDecl>(Y))
213 Y = NY->getUnderlyingDecl();
226 bool AggregateCandidateDeduction =
false) {
239 QualType XType =
X.getNonTypeTemplateArgumentType();
247 switch (
X.getKind()) {
249 llvm_unreachable(
"Non-deduced template arguments handled above");
256 X.wasDeducedFromArrayBound() ||
262 return X.wasDeducedFromArrayBound() ? Y :
X;
276 return X.wasDeducedFromArrayBound() ? Y :
X;
285 X.structurallyEquals(Y)))
313 llvm::FoldingSetNodeID ID1, ID2;
314 X.getAsExpr()->Profile(ID1, Context,
true);
317 return X.wasDeducedFromArrayBound() ? Y :
X;
324 assert(!
X.wasDeducedFromArrayBound());
337 X.getParamTypeForDecl());
374 (!AggregateCandidateDeduction &&
X.pack_size() != Y.
pack_size()))
386 if (Merged.isNull() && !(XA->isNull() && YA->isNull()))
388 NewPack.push_back(Merged);
391 NewPack.push_back(*XA);
401 llvm_unreachable(
"Invalid TemplateArgument Kind!");
414 bool *HasDeducedAnyParam) {
416 "deducing non-type template argument with wrong depth");
420 if (Result.isNull()) {
424 return TemplateDeductionResult::Inconsistent;
429 return TemplateDeductionResult::Success;
436 return TemplateDeductionResult::Success;
441 if (
auto *Expansion = dyn_cast<PackExpansionType>(ParamType))
442 ParamType = Expansion->getPattern();
456 S, TemplateParams, ParamType, ValueType, Info, Deduced,
470 bool *HasDeducedAnyParam) {
472 S, TemplateParams, NTTP,
474 DeducedFromArrayBound),
486 bool *HasDeducedAnyParam) {
508 bool *HasDeducedAnyParam) {
524 bool *HasDeducedAnyParam) {
536 bool *HasDeducedAnyParam) {
541 return TemplateDeductionResult::Success;
544 if (
auto *TempParam = dyn_cast<TemplateTemplateParmDecl>(ParamDecl)) {
547 return TemplateDeductionResult::Success;
551 unsigned StartPos = 0;
568 Arg, {StartPos, DefaultArguments.drop_front(StartPos)}))
572 S.
Context, Deduced[TempParam->getIndex()], NewDeduced);
573 if (Result.isNull()) {
574 Info.
Param = TempParam;
575 Info.
FirstArg = Deduced[TempParam->getIndex()];
577 return TemplateDeductionResult::Inconsistent;
580 Deduced[TempParam->getIndex()] = Result;
581 if (HasDeducedAnyParam)
582 *HasDeducedAnyParam =
true;
583 return TemplateDeductionResult::Success;
589 return TemplateDeductionResult::Success;
594 return TemplateDeductionResult::NonDeducedMismatch;
620 assert(TST &&
"Expected a TemplateSpecializationType");
632 bool *HasDeducedAnyParam) {
635 UP = IP->getInjectedSpecializationType();
643 return TemplateDeductionResult::Success;
650 ->template_arguments();
653 std::optional<NestedNameSpecifier *> NNS;
656 NNS = Elaborated->getQualifier();
658 UA = Injected->getInjectedSpecializationType();
669 return TemplateDeductionResult::Success;
676 ->template_arguments();
683 Result != TemplateDeductionResult::Success)
690 S, TemplateParams, PResolved, AResolved, Info, Deduced,
700 RA ? dyn_cast<ClassTemplateSpecializationDecl>(RA->getDecl()) :
nullptr;
704 return TemplateDeductionResult::NonDeducedMismatch;
710 *NNS,
false,
TemplateName(SA->getSpecializedTemplate()));
714 S, TemplateParams, TNP, TNA, Info,
716 Deduced, HasDeducedAnyParam);
717 Result != TemplateDeductionResult::Success)
722 SA->getTemplateArgs().asArray(), Info, Deduced,
732 case Type::TypeOfExpr:
734 case Type::DependentName:
736 case Type::PackIndexing:
737 case Type::UnresolvedUsing:
738 case Type::TemplateTypeParm:
742 case Type::ConstantArray:
743 case Type::IncompleteArray:
744 case Type::VariableArray:
745 case Type::DependentSizedArray:
747 cast<ArrayType>(
T)->getElementType().getTypePtr());
796class PackDeductionScope {
804 bool DeducePackIfNotAlreadyDeduced =
false,
805 bool FinishingDeduction =
false)
806 : S(S), TemplateParams(TemplateParams), Deduced(Deduced), Info(Info),
807 DeducePackIfNotAlreadyDeduced(DeducePackIfNotAlreadyDeduced),
808 FinishingDeduction(FinishingDeduction) {
809 unsigned NumNamedPacks = addPacks(Pattern);
810 finishConstruction(NumNamedPacks);
817 : S(S), TemplateParams(TemplateParams), Deduced(Deduced), Info(Info) {
819 finishConstruction(1);
823 void addPack(
unsigned Index) {
826 DeducedFromEarlierParameter = !Deduced[Index].isNull();
828 if (!FinishingDeduction) {
829 Pack.Saved = Deduced[Index];
836 if (std::optional<unsigned> ExpandedPackExpansions =
838 FixedNumExpansions = ExpandedPackExpansions;
840 Packs.push_back(Pack);
846 llvm::SmallBitVector SawIndices(TemplateParams->size());
849 auto AddPack = [&](
unsigned Index) {
850 if (SawIndices[Index])
852 SawIndices[Index] =
true;
859 if (
auto *NTTP = dyn_cast<NonTypeTemplateParmDecl>(
860 TemplateParams->getParam(Index))) {
861 if (!NTTP->isExpandedParameterPack())
864 if (
auto *Expansion = dyn_cast<PackExpansionType>(
866 ExtraDeductions.push_back(Expansion->getPattern());
875 for (
unsigned I = 0, N = Unexpanded.size(); I != N; ++I) {
876 unsigned Depth, Index;
878 if (Depth == Info.getDeducedDepth())
885 assert(!Packs.empty() &&
"Pack expansion without unexpanded packs?");
887 unsigned NumNamedPacks = Packs.size();
891 while (!ExtraDeductions.empty())
892 Collect(ExtraDeductions.pop_back_val());
894 return NumNamedPacks;
897 void finishConstruction(
unsigned NumNamedPacks) {
900 unsigned NumPartialPackArgs = 0;
901 std::pair<unsigned, unsigned> PartialPackDepthIndex(-1u, -1u);
903 if (
auto *Partial =
Scope->getPartiallySubstitutedPack(
904 &PartialPackArgs, &NumPartialPackArgs))
910 bool IsExpanded =
true;
911 for (
unsigned I = 0; I != NumNamedPacks; ++I) {
912 if (Packs[I].Index >= Info.getNumExplicitArgs()) {
914 IsPartiallyExpanded =
false;
917 if (PartialPackDepthIndex ==
918 std::make_pair(Info.getDeducedDepth(), Packs[I].Index)) {
919 IsPartiallyExpanded =
true;
927 if (IsPartiallyExpanded)
928 PackElements += NumPartialPackArgs;
929 else if (IsExpanded && FixedNumExpansions)
930 PackElements += *FixedNumExpansions;
932 for (
auto &Pack : Packs) {
933 if (Info.PendingDeducedPacks.size() > Pack.Index)
934 Pack.Outer = Info.PendingDeducedPacks[Pack.Index];
936 Info.PendingDeducedPacks.resize(Pack.Index + 1);
937 Info.PendingDeducedPacks[Pack.Index] = &Pack;
939 if (PartialPackDepthIndex ==
940 std::make_pair(Info.getDeducedDepth(), Pack.Index)) {
941 Pack.New.append(PartialPackArgs, PartialPackArgs + NumPartialPackArgs);
950 if (!FinishingDeduction && !IsPartiallyExpanded)
951 Deduced[Pack.Index] = Pack.New[PackElements];
957 ~PackDeductionScope() {
958 for (
auto &Pack : Packs)
959 Info.PendingDeducedPacks[Pack.Index] = Pack.Outer;
963 std::optional<unsigned> getSavedPackSizeIfAllEqual()
const {
964 unsigned PackSize = Packs[0].Saved.pack_size();
966 if (std::all_of(Packs.begin() + 1, Packs.end(), [&PackSize](
const auto &
P) {
967 return P.Saved.pack_size() == PackSize;
975 bool isDeducedFromEarlierParameter()
const {
976 return DeducedFromEarlierParameter;
981 bool isPartiallyExpanded() {
return IsPartiallyExpanded; }
986 bool hasFixedArity() {
return FixedNumExpansions.has_value(); }
991 bool hasNextElement() {
992 return !FixedNumExpansions || *FixedNumExpansions > PackElements;
996 void nextPackElement() {
1000 if (!FinishingDeduction) {
1001 for (
auto &Pack : Packs) {
1003 if (!Pack.New.empty() || !DeducedArg.
isNull()) {
1004 while (Pack.New.size() < PackElements)
1006 if (Pack.New.size() == PackElements)
1007 Pack.New.push_back(DeducedArg);
1009 Pack.New[PackElements] = DeducedArg;
1010 DeducedArg = Pack.New.size() > PackElements + 1
1011 ? Pack.New[PackElements + 1]
1023 if (FinishingDeduction)
1024 return TemplateDeductionResult::Success;
1027 for (
auto &Pack : Packs) {
1029 if (!FinishingDeduction)
1030 Deduced[Pack.Index] = Pack.Saved;
1045 Pack.New.resize(PackElements);
1049 if (Pack.New.empty()) {
1055 std::copy(Pack.New.begin(), Pack.New.end(), ArgumentPack);
1063 Pack.New[0].wasDeducedFromArrayBound());
1069 if (Pack.Outer->DeferredDeduction.isNull()) {
1072 Pack.Outer->DeferredDeduction = NewPack;
1075 Loc = &Pack.Outer->DeferredDeduction;
1077 Loc = &Deduced[Pack.Index];
1083 S.
Context, OldPack, NewPack, DeducePackIfNotAlreadyDeduced);
1085 Info.AggregateDeductionCandidateHasMismatchedArity =
1091 if (!Result.isNull() && !Pack.DeferredDeduction.isNull()) {
1093 NewPack = Pack.DeferredDeduction;
1097 NamedDecl *Param = TemplateParams->getParam(Pack.Index);
1098 if (Result.isNull()) {
1100 Info.FirstArg = OldPack;
1101 Info.SecondArg = NewPack;
1102 return TemplateDeductionResult::Inconsistent;
1108 if (*Expansions != PackElements) {
1110 Info.FirstArg = Result;
1111 return TemplateDeductionResult::IncompletePack;
1118 return TemplateDeductionResult::Success;
1126 unsigned PackElements = 0;
1127 bool IsPartiallyExpanded =
false;
1128 bool DeducePackIfNotAlreadyDeduced =
false;
1129 bool DeducedFromEarlierParameter =
false;
1130 bool FinishingDeduction =
false;
1132 std::optional<unsigned> FixedNumExpansions;
1144 bool FinishingDeduction,
T &&DeductFunc) {
1154 = dyn_cast<PackExpansionType>(Params[
ParamIdx]);
1159 if (ArgIdx >= Args.size())
1160 return TemplateDeductionResult::MiscellaneousDeductionFailure;
1162 if (isa<PackExpansionType>(Args[ArgIdx])) {
1167 return TemplateDeductionResult::MiscellaneousDeductionFailure;
1171 DeductFunc(S, TemplateParams,
ParamIdx, ArgIdx,
1172 Params[
ParamIdx].getUnqualifiedType(),
1173 Args[ArgIdx].getUnqualifiedType(), Info, Deduced, POK);
1174 Result != TemplateDeductionResult::Success)
1189 PackDeductionScope PackScope(S, TemplateParams, Deduced, Info, Pattern,
1191 FinishingDeduction);
1195 if (
ParamIdx + 1 == Params.size() || PackScope.hasFixedArity()) {
1196 for (; ArgIdx < Args.size() && PackScope.hasNextElement(); ++ArgIdx) {
1199 S, TemplateParams,
ParamIdx, ArgIdx,
1201 Info, Deduced, POK);
1202 Result != TemplateDeductionResult::Success)
1204 PackScope.nextPackElement();
1225 if (NumExpansions && !PackScope.isPartiallyExpanded()) {
1226 for (
unsigned I = 0; I != *NumExpansions && ArgIdx < Args.size();
1228 PackScope.nextPackElement();
1234 if (
auto Result = PackScope.finish();
1235 Result != TemplateDeductionResult::Success)
1246 isa<PackExpansionType>(Args[ArgIdx]))
1247 return TemplateDeductionResult::Success;
1250 if (ArgIdx < Args.size())
1251 return TemplateDeductionResult::MiscellaneousDeductionFailure;
1253 return TemplateDeductionResult::Success;
1293 llvm::SmallBitVector *HasDeducedParam) {
1294 return ::DeduceForEachType(
1295 S, TemplateParams, Params, Args, Info, Deduced, POK,
1301 bool HasDeducedAnyParamCopy =
false;
1303 S, TemplateParams,
P, A, Info, Deduced, TDF, POK,
1304 false, &HasDeducedAnyParamCopy);
1305 if (HasDeducedAnyParam && HasDeducedAnyParamCopy)
1306 *HasDeducedAnyParam =
true;
1307 if (HasDeducedParam && HasDeducedAnyParamCopy)
1308 (*HasDeducedParam)[
ParamIdx] =
true;
1322 if (ParamQs == ArgQs)
1366 if (!Guide || !Guide->isImplicit())
1368 return Guide->getDeducedTemplate()->getTemplateParameters()->size();
1378 if (ParamRef->getPointeeType().getQualifiers())
1381 return TypeParm && TypeParm->
getIndex() >= FirstInnerIndex;
1409 bool *HasDeducedAnyParam) {
1435 bool HasDeducedAnyParam;
1437 llvm::MapVector<const CXXRecordDecl *, MatchValue> Matches;
1442 assert(
T->
isRecordType() &&
"Base class that isn't a record?");
1444 ToVisit.push_back(
T);
1453 while (!ToVisit.empty()) {
1454 QualType NextT = ToVisit.pop_back_val();
1459 bool HasDeducedAnyParamCopy =
false;
1462 &HasDeducedAnyParamCopy);
1468 Matches.insert({RD, {DeducedCopy, HasDeducedAnyParamCopy}});
1479 if (Matches.size() > 1) {
1481 for (
const auto &Match : Matches)
1482 AddBases(Match.first);
1486 while (Matches.size() > 1 && !ToVisit.empty()) {
1487 const CXXRecordDecl *RD = ToVisit.pop_back_val()->getAsCXXRecordDecl();
1496 if (Matches.empty())
1498 if (Matches.size() > 1)
1501 std::swap(Matches.front().second.Deduced, Deduced);
1502 if (
bool HasDeducedAnyParamCopy = Matches.front().second.HasDeducedAnyParam;
1503 HasDeducedAnyParamCopy && HasDeducedAnyParam)
1504 *HasDeducedAnyParam = HasDeducedAnyParamCopy;
1513 return std::min(POK, PartialOrderingKind::NonCall);
1545 bool *HasDeducedAnyParam) {
1549 if (
const auto *AExp = dyn_cast<PackExpansionType>(A))
1550 A = AExp->getPattern();
1553 if (POK == PartialOrderingKind::Call) {
1631 TDF &= ~TDF_TopLevelParameterTypeList;
1634 P =
P->getPointeeType();
1651 unsigned Index = TTP->getIndex();
1666 Info.
Param = cast<TemplateTypeParmDecl>(TemplateParams->
getParam(Index));
1678 "saw template type parameter with wrong depth");
1680 "Unresolved overloaded function");
1700 Info.
Param = cast<TemplateTypeParmDecl>(TemplateParams->
getParam(Index));
1723 case Decl::TemplateTypeParm:
1724 Info.
Param = cast<TemplateTypeParmDecl>(Param);
1726 case Decl::NonTypeTemplateParm:
1727 Info.
Param = cast<NonTypeTemplateParmDecl>(Param);
1729 case Decl::TemplateTemplateParm:
1730 Info.
Param = cast<TemplateTemplateParmDecl>(Param);
1733 llvm_unreachable(
"unexpected kind");
1741 if (HasDeducedAnyParam)
1742 *HasDeducedAnyParam =
true;
1782 if (!
P->isDependentType()) {
1798 switch (
P.getCanonicalType()->getTypeClass()) {
1800#define NON_CANONICAL_TYPE(Class, Base) \
1801 case Type::Class: llvm_unreachable("deducing non-canonical type: " #Class);
1802#define TYPE(Class, Base)
1803#include "clang/AST/TypeNodes.inc"
1805 case Type::TemplateTypeParm:
1806 case Type::SubstTemplateTypeParmPack:
1807 llvm_unreachable(
"Type nodes handled above");
1815 if (
P->isDependentType())
1819 case Type::VariableArray:
1821 case Type::FunctionNoProto:
1824 case Type::ObjCObject:
1825 case Type::ObjCInterface:
1826 case Type::ObjCObjectPointer:
1836 case Type::Complex: {
1841 S, TemplateParams, CP->getElementType(), CA->getElementType(), Info,
1843 false, HasDeducedAnyParam);
1847 case Type::Atomic: {
1852 S, TemplateParams, PA->getValueType(), AA->getValueType(), Info,
1854 false, HasDeducedAnyParam);
1858 case Type::Pointer: {
1869 PointeeType, Info, Deduced,
1872 false, HasDeducedAnyParam);
1876 case Type::LValueReference: {
1883 S, TemplateParams, RP->getPointeeType(), RA->getPointeeType(), Info,
1885 false, HasDeducedAnyParam);
1889 case Type::RValueReference: {
1896 S, TemplateParams, RP->getPointeeType(), RA->getPointeeType(), Info,
1898 false, HasDeducedAnyParam);
1902 case Type::IncompleteArray: {
1908 assert(IAP &&
"Template parameter not of incomplete array type");
1911 S, TemplateParams, IAP->getElementType(), IAA->getElementType(), Info,
1914 false, HasDeducedAnyParam);
1918 case Type::ConstantArray: {
1922 if (!CAA || CAA->getSize() != CAP->getSize())
1926 S, TemplateParams, CAP->getElementType(), CAA->getElementType(), Info,
1929 false, HasDeducedAnyParam);
1933 case Type::DependentSizedArray: {
1942 S, TemplateParams, DAP->getElementType(), AA->getElementType(),
1945 false, HasDeducedAnyParam);
1958 "saw non-type template parameter with wrong depth");
1959 if (
const auto *CAA = dyn_cast<ConstantArrayType>(AA)) {
1960 llvm::APSInt Size(CAA->getSize());
1963 true, Info, POK != PartialOrderingKind::None,
1964 Deduced, HasDeducedAnyParam);
1966 if (
const auto *DAA = dyn_cast<DependentSizedArrayType>(AA))
1967 if (DAA->getSizeExpr())
1969 S, TemplateParams, NTTP, DAA->getSizeExpr(), Info,
1970 POK != PartialOrderingKind::None, Deduced, HasDeducedAnyParam);
1979 case Type::FunctionProto: {
1985 if (FPP->getMethodQuals() != FPA->getMethodQuals() ||
1986 FPP->getRefQualifier() != FPA->getRefQualifier() ||
1987 FPP->isVariadic() != FPA->isVariadic())
1992 S, TemplateParams, FPP->getReturnType(), FPA->getReturnType(),
1994 false, HasDeducedAnyParam);
2000 S, TemplateParams, FPP->param_types(), FPA->param_types(), Info,
2013 Expr *NoexceptExpr = FPP->getNoexceptExpr();
2018 "saw non-type template parameter with wrong depth");
2020 llvm::APSInt Noexcept(1);
2021 switch (FPA->canThrow()) {
2032 POK != PartialOrderingKind::None, Deduced, HasDeducedAnyParam);
2035 if (
Expr *ArgNoexceptExpr = FPA->getNoexceptExpr())
2037 S, TemplateParams, NTTP, ArgNoexceptExpr, Info,
2038 POK != PartialOrderingKind::None, Deduced, HasDeducedAnyParam);
2051 case Type::InjectedClassName:
2060 case Type::TemplateSpecialization: {
2065 POK != PartialOrderingKind::None,
2066 Deduced, HasDeducedAnyParam);
2072 S, TemplateParams,
P, A, Info, POK != PartialOrderingKind::None,
2073 Deduced, HasDeducedAnyParam);
2088 Deduced = DeducedOrig;
2092 POK != PartialOrderingKind::None,
2093 Deduced, HasDeducedAnyParam);
2107 case Type::MemberPointer: {
2124 S, TemplateParams, PPT, APT, Info, Deduced, SubTDF,
2126 false, HasDeducedAnyParam);
2130 S, TemplateParams,
QualType(MPP->getClass(), 0),
2131 QualType(MPA->getClass(), 0), Info, Deduced, SubTDF,
2133 false, HasDeducedAnyParam);
2141 case Type::BlockPointer: {
2147 S, TemplateParams, BPP->getPointeeType(), BPA->getPointeeType(), Info,
2149 false, HasDeducedAnyParam);
2155 case Type::ExtVector: {
2160 if (VP->getNumElements() != VA->getNumElements())
2162 ElementType = VA->getElementType();
2167 ElementType = VA->getElementType();
2173 S, TemplateParams, VP->getElementType(), ElementType, Info, Deduced,
2175 false, HasDeducedAnyParam);
2178 case Type::DependentVector: {
2184 S, TemplateParams, VP->getElementType(), VA->getElementType(),
2186 false, HasDeducedAnyParam);
2197 ArgSize = VA->getNumElements();
2203 Info, POK != PartialOrderingKind::None, Deduced,
2204 HasDeducedAnyParam);
2210 S, TemplateParams, VP->getElementType(), VA->getElementType(),
2212 false, HasDeducedAnyParam);
2223 S, TemplateParams, NTTP, VA->getSizeExpr(), Info,
2224 POK != PartialOrderingKind::None, Deduced, HasDeducedAnyParam);
2233 case Type::DependentSizedExtVector: {
2239 S, TemplateParams, VP->getElementType(), VA->getElementType(),
2241 false, HasDeducedAnyParam);
2252 ArgSize = VA->getNumElements();
2257 S, TemplateParams, NTTP, ArgSize, S.
Context.
IntTy,
true, Info,
2258 POK != PartialOrderingKind::None, Deduced, HasDeducedAnyParam);
2264 S, TemplateParams, VP->getElementType(), VA->getElementType(),
2266 false, HasDeducedAnyParam);
2277 S, TemplateParams, NTTP, VA->getSizeExpr(), Info,
2278 POK != PartialOrderingKind::None, Deduced, HasDeducedAnyParam);
2288 case Type::ConstantMatrix: {
2295 if (MP->getNumRows() != MA->getNumRows() ||
2296 MP->getNumColumns() != MA->getNumColumns()) {
2301 S, TemplateParams, MP->getElementType(), MA->getElementType(), Info,
2303 false, HasDeducedAnyParam);
2306 case Type::DependentSizedMatrix: {
2316 false, HasDeducedAnyParam);
2321 auto DeduceMatrixArg =
2322 [&S, &Info, &Deduced, &TemplateParams, &HasDeducedAnyParam, POK](
2326 const auto *ACM = dyn_cast<ConstantMatrixType>(A);
2327 const auto *ADM = dyn_cast<DependentSizedMatrixType>(A);
2328 if (!ParamExpr->isValueDependent()) {
2329 std::optional<llvm::APSInt> ParamConst =
2330 ParamExpr->getIntegerConstantExpr(S.
Context);
2335 if ((ACM->*GetArgDimension)() == *ParamConst)
2340 Expr *ArgExpr = (ADM->*GetArgDimensionExpr)();
2341 if (std::optional<llvm::APSInt> ArgConst =
2343 if (*ArgConst == *ParamConst)
2354 llvm::APSInt ArgConst(
2356 ArgConst = (ACM->*GetArgDimension)();
2359 true, Info, POK != PartialOrderingKind::None,
2360 Deduced, HasDeducedAnyParam);
2364 S, TemplateParams, NTTP, (ADM->*GetArgDimensionExpr)(), Info,
2365 POK != PartialOrderingKind::None, Deduced, HasDeducedAnyParam);
2368 if (
auto Result = DeduceMatrixArg(MP->getRowExpr(), MA,
2374 return DeduceMatrixArg(MP->getColumnExpr(), MA,
2382 case Type::DependentAddressSpace: {
2388 S, TemplateParams, ASP->getPointeeType(), ASA->getPointeeType(),
2390 false, HasDeducedAnyParam);
2401 S, TemplateParams, NTTP, ASA->getAddrSpaceExpr(), Info,
2402 POK != PartialOrderingKind::None, Deduced, HasDeducedAnyParam);
2412 S, TemplateParams, ASP->getPointeeType(),
2415 false, HasDeducedAnyParam);
2426 S, TemplateParams, NTTP, ArgAddressSpace, S.
Context.
IntTy,
true,
2427 Info, POK != PartialOrderingKind::None, Deduced,
2428 HasDeducedAnyParam);
2433 case Type::DependentBitInt: {
2437 if (IP->isUnsigned() != IA->isUnsigned())
2446 ArgSize = IA->getNumBits();
2449 S, TemplateParams, NTTP, ArgSize, S.
Context.
IntTy,
true, Info,
2450 POK != PartialOrderingKind::None, Deduced, HasDeducedAnyParam);
2454 if (IP->isUnsigned() != IA->isUnsigned())
2462 case Type::TypeOfExpr:
2464 case Type::DependentName:
2465 case Type::UnresolvedUsing:
2466 case Type::Decltype:
2467 case Type::UnaryTransform:
2468 case Type::DeducedTemplateSpecialization:
2469 case Type::DependentTemplateSpecialization:
2470 case Type::PackExpansion:
2472 case Type::ArrayParameter:
2473 case Type::HLSLAttributedResource:
2477 case Type::PackIndexing: {
2483 false, HasDeducedAnyParam);
2489 llvm_unreachable(
"Invalid Type Class!");
2497 bool *HasDeducedAnyParam) {
2504 switch (
P.getKind()) {
2506 llvm_unreachable(
"Null template argument in parameter list");
2511 S, TemplateParams,
P.getAsType(), A.
getAsType(), Info, Deduced, 0,
2513 : PartialOrderingKind::None,
2514 false, HasDeducedAnyParam);
2526 HasDeducedAnyParam);
2532 llvm_unreachable(
"caller should handle pack expansions");
2582 if (
const auto *ICE = dyn_cast<ImplicitCastExpr>(
E);
2583 ICE && ICE->getCastKind() == clang::CK_Dependent) {
2584 E = ICE->getSubExpr();
2586 S, TemplateParams, ICE->getType(),
E->
getType(), Info,
2589 : PartialOrderingKind::None,
2590 false, HasDeducedAnyParam);
2603 HasDeducedAnyParam);
2608 Deduced, HasDeducedAnyParam);
2624 llvm_unreachable(
"Unknown template argument kind");
2630 llvm_unreachable(
"Argument packs should be expanded by the caller!");
2633 llvm_unreachable(
"Invalid TemplateArgument Kind!");
2646 if (ArgIdx == Args.size())
2653 assert(ArgIdx == Args.size() - 1 &&
"Pack not at the end of argument list?");
2656 return ArgIdx < Args.size();
2662 bool FoundPackExpansion =
false;
2663 for (
const auto &A : Args) {
2664 if (FoundPackExpansion)
2672 if (A.isPackExpansion())
2673 FoundPackExpansion =
true;
2687 bool FoldPackParameter =
PackFold == PackFold::ParameterToArgument ||
2689 FoldPackArgument =
PackFold == PackFold::ArgumentToParameter ||
2703 for (
unsigned ArgIdx = 0,
ParamIdx = 0; ; ) {
2709 if (!Ps[
ParamIdx].isPackExpansion()) {
2714 return !FoldPackArgument && NumberOfArgumentsMustMatch
2718 if (As[ArgIdx].isPackExpansion()) {
2723 if (!FoldPackArgument)
2730 S, TemplateParams, Ps[
ParamIdx], Pattern, Info,
2738 if (Ps[
ParamIdx].isPackExpansion())
2744 S, TemplateParams, Ps[
ParamIdx], As[ArgIdx], Info,
2765 PackDeductionScope PackScope(S, TemplateParams, Deduced, Info, Pattern);
2771 PackScope.hasNextElement();
2773 if (!As[ArgIdx].isPackExpansion()) {
2774 if (!FoldPackParameter)
2776 if (FoldPackArgument)
2782 Deduced, HasDeducedAnyParam);
2786 PackScope.nextPackElement();
2791 return PackScope.finish();
2799 bool NumberOfArgumentsMustMatch) {
2800 return ::DeduceTemplateArguments(
2801 *
this, TemplateParams, Ps, As, Info, Deduced, NumberOfArgumentsMustMatch,
2802 false, PackFold::ParameterToArgument,
2811 bool PackExpansionMatchesPack =
false) {
2814 if (PackExpansionMatchesPack &&
X.isPackExpansion() && !Y.
isPackExpansion())
2815 X =
X.getPackExpansionPattern();
2820 switch (
X.getKind()) {
2822 llvm_unreachable(
"Comparing NULL template argument");
2845 return X.structurallyEquals(Y);
2848 llvm::FoldingSetNodeID XID, YID;
2849 X.getAsExpr()->Profile(XID, Context,
true);
2855 unsigned PackIterationSize =
X.pack_size();
2864 bool XHasMoreArg =
X.pack_size() > Y.
pack_size();
2865 if (!(XHasMoreArg &&
X.pack_elements().back().isPackExpansion()) &&
2866 !(!XHasMoreArg && Y.
pack_elements().back().isPackExpansion()))
2875 for (
unsigned i = 0; i < PackIterationSize; ++i)
2877 PackExpansionMatchesPack))
2883 llvm_unreachable(
"Invalid TemplateArgument Kind!");
2892 llvm_unreachable(
"Can't get a NULL template argument here");
2927 Builder.MakeTrivial(
Context, DTN->getQualifier(),
Loc);
2930 Builder.MakeTrivial(
Context, QTN->getQualifier(),
Loc);
2947 llvm_unreachable(
"Invalid TemplateArgument Kind!");
2965 unsigned ArgumentPackIndex) {
2972 bool MatchedPackOnParmToNonPackOnArg =
false;
2983 if (MatchedPackOnParmToNonPackOnArg)
2992 CanonicalPackedArgsBuilder;
3000 "deduced nested pack");
3007 diag::err_template_arg_deduced_incomplete_pack)
3011 if (ConvertArg(InnerArg, SugaredPackedArgsBuilder.size()))
3015 SugaredPackedArgsBuilder.push_back(SugaredOutput.pop_back_val());
3016 CanonicalPackedArgsBuilder.push_back(CanonicalOutput.pop_back_val());
3021 if (SugaredPackedArgsBuilder.empty()) {
3026 if (
auto *NTTP = dyn_cast<NonTypeTemplateParmDecl>(Param)) {
3028 NTTP, SugaredOutput,
3031 S.
SubstType(NTTP->getType(), Args, NTTP->getLocation(),
3032 NTTP->getDeclName()).isNull())
3034 }
else if (
auto *TTP = dyn_cast<TemplateTemplateParmDecl>(Param)) {
3045 SugaredOutput.push_back(
3048 S.
Context, CanonicalPackedArgsBuilder));
3052 return ConvertArg(Arg, 0);
3062template <
typename TemplateDeclT>
3064 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) {
3103 SugaredBuilder.push_back(Deduced[I]);
3104 CanonicalBuilder.push_back(
3114 SugaredBuilder, CanonicalBuilder)) {
3132 *IsIncomplete =
true;
3133 SugaredBuilder.push_back({});
3134 CanonicalBuilder.push_back({});
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();
3163 SugaredBuilder, CanonicalBuilder, HasDefaultArg);
3180 0, SugaredBuilder, CanonicalBuilder,
3198 if (
auto *DC = dyn_cast<DeclContext>(
D))
3204 static constexpr bool value =
false;
3208 static constexpr bool value =
true;
3212 static constexpr bool value =
true;
3214template <
typename TemplateDeclT>
3229template <
typename TemplateDeclT>
3236 Template->getAssociatedConstraints(AssociatedConstraints);
3238 std::optional<ArrayRef<TemplateArgument>> Innermost;
3242 Innermost = CanonicalDeducedArgs;
3245 Template, Template->getDeclContext(),
false, Innermost,
3269template <
typename T>
3270static std::enable_if_t<IsPartialSpecialization<T>::value,
3273 Sema &S,
T *Partial,
bool IsPartialOrdering,
3289 S, Partial, IsPartialOrdering, Deduced, Info, SugaredBuilder,
3290 CanonicalBuilder, IsPartialOrdering,
3302 Info.
reset(SugaredDeducedArgumentList, CanonicalDeducedArgumentList);
3310 auto *Template = Partial->getSpecializedTemplate();
3312 Partial->getTemplateArgsAsWritten();
3323 if (
ParamIdx >= Partial->getTemplateParameters()->size())
3324 ParamIdx = Partial->getTemplateParameters()->size() - 1;
3327 Partial->getTemplateParameters()->getParam(
ParamIdx));
3329 Info.
FirstArg = (*PartialTemplArgInfo)[ArgIdx].getArgument();
3333 bool MatchedPackOnParmToNonPackOnArg =
false;
3336 CanonicalConvertedInstArgs;
3338 Template, Partial->getLocation(), InstArgs, {},
false,
3339 SugaredConvertedInstArgs, CanonicalConvertedInstArgs,
3341 false, &MatchedPackOnParmToNonPackOnArg))
3345 if (MatchedPackOnParmToNonPackOnArg)
3349 for (
unsigned I = 0,
E = TemplateParams->
size(); I !=
E; ++I) {
3352 IsPartialOrdering)) {
3363 if (!IsPartialOrdering) {
3365 S, Partial, SugaredBuilder, CanonicalBuilder, Info);
3401 AsStack{CanonicalBuilder};
3405 while (!Stack.empty()) {
3406 auto &Xs = Stack.back();
3411 auto &
X = Xs.front();
3413 Stack.emplace_back(
X.getPackAsArray());
3414 Xs = Xs.drop_front();
3417 assert(!
X.isNull());
3424 auto [Ps,
P] = take(PsStack);
3425 auto [As, A] = take(AsStack);
3426 if (
P.isNull() && A.isNull())
3429 PA = A.isPackExpansion() ? A.getPackExpansionPattern() : A;
3431 if (!
P.isPackExpansion() && !A.isPackExpansion()) {
3434 (PsStack.empty() ? TemplateArgs.end()
3435 : PsStack.front().begin()) -
3436 TemplateArgs.begin()));
3441 if (
P.isPackExpansion()) {
3442 Ps = Ps.drop_front();
3445 if (A.isPackExpansion()) {
3446 As = As.drop_front();
3450 Ps = Ps.drop_front(
P.isPackExpansion() ? 0 : 1);
3451 As = As.drop_front(A.isPackExpansion() && !
P.isPackExpansion() ? 0 : 1);
3453 assert(PsStack.empty());
3454 assert(AsStack.empty());
3458 S, Template, SugaredBuilder, CanonicalBuilder, Info);
3484 S, TD,
false, Deduced, Info, SugaredBuilder,
3485 CanonicalBuilder,
false,
3491 return ::CheckDeducedArgumentConstraints(S, TD, SugaredBuilder,
3492 CanonicalBuilder, Info);
3498template <
typename T>
3499static std::enable_if_t<IsPartialSpecialization<T>::value,
3504 if (Partial->isInvalidDecl())
3523 Deduced.resize(Partial->getTemplateParameters()->size());
3525 S, Partial->getTemplateParameters(),
3526 Partial->getTemplateArgs().asArray(), TemplateArgs, Info, Deduced,
3528 PackFold::ParameterToArgument,
3541 Result = ::FinishTemplateArgumentDeduction(S, Partial,
3543 TemplateArgs, Deduced, Info);
3559 return ::DeduceTemplateArguments(*
this, Partial, TemplateArgs, Info);
3565 return ::DeduceTemplateArguments(*
this, Partial, TemplateArgs, Info);
3575 if (
const auto *CTD = dyn_cast<ClassTemplateDecl>(TD)) {
3578 }
else if (
const auto *
AliasTemplate = dyn_cast<TypeAliasTemplateDecl>(TD)) {
3579 PType =
AliasTemplate->getTemplatedDecl()->getUnderlyingType();
3581 assert(
false &&
"Expected a class or alias template");
3600 return DeducedResult;
3610 Result = ::FinishTemplateArgumentDeduction(*this, TD, Deduced, Info);
3626 return Spec->getTemplateName().getAsTemplateDecl() !=
nullptr;
3652 if (ExplicitTemplateArgs.
size() == 0) {
3656 ParamTypes.push_back(
P->getType());
3686 ExplicitTemplateArgs, {},
true,
3687 SugaredBuilder, CanonicalBuilder,
3690 unsigned Index = SugaredBuilder.size();
3691 if (Index >= TemplateParams->
size())
3704 CanonicalExplicitArgumentList);
3716 unsigned PartiallySubstitutedPackIndex = -1u;
3717 if (!SugaredBuilder.empty()) {
3720 auto *Param = TemplateParams->
getParam(SugaredBuilder.size() - 1);
3724 if (!Expansions || Arg.
pack_size() < *Expansions) {
3725 PartiallySubstitutedPackIndex = SugaredBuilder.size() - 1;
3734 assert(Proto &&
"Function template does not have a prototype?");
3742 SugaredExplicitArgumentList->
asArray(),
3752 nullptr, ExtParamInfos))
3769 ThisTypeQuals = Method->getMethodQualifiers();
3783 Diag(
Function->getLocation(), diag::err_kern_type_not_void_return)
3794 nullptr, ExtParamInfos))
3818 Deduced.reserve(TemplateParams->
size());
3819 for (
unsigned I = 0, N = SugaredExplicitArgumentList->
size(); I != N; ++I) {
3821 if (I == PartiallySubstitutedPackIndex)
3824 Deduced.push_back(Arg);
3893 if (AQuals == DeducedAQuals) {
3911 bool ObjCLifetimeConversion =
false;
3915 ObjCLifetimeConversion) ||
3961 if (PD->isParameterPack()) {
3962 unsigned NumExpansions =
3964 if (Idx + NumExpansions >
ParamIdx)
3966 Idx += NumExpansions;
3974 llvm_unreachable(
"parameter index would not be produced from template");
3986 return isa<CXXConstructorDecl>(
D)
3987 ? cast<CXXConstructorDecl>(
D)->getExplicitSpecifier()
3988 : cast<CXXConversionDecl>(
D)->getExplicitSpecifier();
3991 isa<CXXConstructorDecl>(
D)
3992 ? cast<CXXConstructorDecl>(
D)->setExplicitSpecifier(ES)
3993 : cast<CXXConversionDecl>(
D)->setExplicitSpecifier(ES);
4004 S, Info.
getLocation(), FunctionTemplate, DeducedArgs,
4026 llvm::function_ref<
bool()> CheckNonDependent) {
4046 bool IsIncomplete =
false;
4052 PartialOverloading ? &IsIncomplete :
nullptr);
4065 if (CheckNonDependent())
4073 Info.
reset(SugaredDeducedArgumentList, CanonicalDeducedArgumentList);
4111 CanonicalDeducedArgumentList &&
4131 if (!IsIncomplete) {
4147 if (isa<CXXConstructorDecl, CXXConversionDecl>(
Specialization)) {
4156 if (OriginalCallArgs) {
4161 llvm::SmallDenseMap<std::pair<unsigned, QualType>,
QualType> DeducedATypes;
4162 for (
unsigned I = 0, N = OriginalCallArgs->size(); I != N; ++I) {
4166 unsigned ExplicitOffset =
4186 if (CacheEntry.
isNull()) {
4195 DeducedA = CacheEntry;
4210 auto [Pos, Inserted] =
4224 if (S.
getLangOpts().CPlusPlus14 && Fn->getReturnType()->isUndeducedType() &&
4229 if (Method->isImplicitObjectMemberFunction()) {
4250 bool ParamWasReference,
4259 if (ParamWasReference)
4276 nullptr, FailedTSC))
4317 if (ArgType.
isNull())
continue;
4337 Deduced(TemplateParams->
size());
4340 S, TemplateParams, ParamType, ArgType, Info, Deduced, TDF,
4341 PartialOrderingKind::None,
false,
4380 assert(Arg &&
"expected a non-null arg expression");
4382 ParamRefType !=
nullptr, FailedTSC);
4390 assert(Arg &&
"expected a non-null arg expression");
4445 (isa<PointerType>(ParamType) &&
4464 bool DecomposedParam,
unsigned ArgIdx,
unsigned TDF,
4489 ElTy = ArrTy->getElementType();
4499 if (isa<DesignatedInitExpr>(
E))
4506 S, TemplateParams, 0, ElTy,
E->
getType(),
4508 OriginalCallArgs,
true, ArgIdx, TDF);
4516 if (
auto *DependentArrTy = dyn_cast_or_null<DependentSizedArrayType>(ArrTy)) {
4527 S, TemplateParams, NTTP, llvm::APSInt(Size),
T,
4528 true, Info,
false, Deduced,
4547 bool DecomposedParam,
unsigned ArgIdx,
unsigned TDF,
4550 QualType OrigParamType = ParamType;
4555 S, TemplateParams, FirstInnerIndex, ParamType, ArgType,
4556 ArgClassification, Arg, TDF, FailedTSC))
4560 if (
InitListExpr *ILE = dyn_cast_if_present<InitListExpr>(Arg))
4562 Deduced, OriginalCallArgs, ArgIdx, TDF);
4570 OriginalCallArgs.push_back(
4573 S, TemplateParams, ParamType, ArgType, Info, Deduced, TDF,
4574 PartialOrderingKind::None,
false,
4582 bool PartialOverloading,
bool AggregateDeductionCandidate,
4590 unsigned NumParams =
Function->getNumParams();
4591 bool HasExplicitObject =
false;
4592 int ExplicitObjectOffset = 0;
4593 if (
Function->hasCXXExplicitFunctionObjectParameter()) {
4594 HasExplicitObject =
true;
4595 ExplicitObjectOffset = 1;
4604 if (Args.size() <
Function->getMinRequiredExplicitArguments() &&
4605 !PartialOverloading)
4608 PartialOverloading)) {
4610 if (Proto->isTemplateVariadic())
4612 else if (!Proto->isVariadic())
4623 unsigned NumExplicitlySpecified = 0;
4624 if (ExplicitTemplateArgs) {
4627 Result = SubstituteExplicitTemplateArguments(
4628 FunctionTemplate, *ExplicitTemplateArgs, Deduced, ParamTypes, nullptr,
4634 NumExplicitlySpecified = Deduced.size();
4637 for (
unsigned I = 0; I != NumParams; ++I)
4638 ParamTypes.push_back(
Function->getParamDecl(I)->getType());
4644 auto DeduceCallArgument = [&](
QualType ParamType,
unsigned ArgIdx,
4645 bool ExplicitObjectArgument) {
4653 if (ExplicitObjectArgument) {
4656 *
this, TemplateParams, FirstInnerIndex, ParamType, ObjectType,
4657 ObjectClassification,
4658 nullptr, Info, Deduced, OriginalCallArgs,
4664 *
this, TemplateParams, FirstInnerIndex, ParamType,
4665 Args[ArgIdx]->getType(), Args[ArgIdx]->Classify(
getASTContext()),
4666 Args[ArgIdx], Info, Deduced, OriginalCallArgs,
false,
4671 Deduced.resize(TemplateParams->
size());
4673 for (
unsigned ParamIdx = 0, NumParamTypes = ParamTypes.size(), ArgIdx = 0;
4678 dyn_cast<PackExpansionType>(ParamType);
4679 if (!ParamExpansion) {
4681 if (ArgIdx >= Args.size() && !(HasExplicitObject &&
ParamIdx == 0))
4684 ParamTypesForArgChecking.push_back(ParamType);
4686 if (
ParamIdx == 0 && HasExplicitObject) {
4690 if (
auto Result = DeduceCallArgument(ParamType, 0,
4697 if (
auto Result = DeduceCallArgument(ParamType, ArgIdx++,
4705 bool IsTrailingPack =
ParamIdx + 1 == NumParamTypes;
4708 PackDeductionScope PackScope(*
this, TemplateParams, Deduced, Info,
4710 AggregateDeductionCandidate && IsTrailingPack);
4728 if (IsTrailingPack || PackScope.hasFixedArity()) {
4729 for (; ArgIdx < Args.size() && PackScope.hasNextElement();
4730 PackScope.nextPackElement(), ++ArgIdx) {
4731 ParamTypesForArgChecking.push_back(ParamPattern);
4732 if (
auto Result = DeduceCallArgument(ParamPattern, ArgIdx,
4741 std::optional<unsigned> NumExpansions =
4743 if (NumExpansions && !PackScope.isPartiallyExpanded()) {
4744 for (
unsigned I = 0; I != *NumExpansions && ArgIdx < Args.size();
4746 ParamTypesForArgChecking.push_back(ParamPattern);
4749 PackScope.nextPackElement();
4751 }
else if (!IsTrailingPack && !PackScope.isPartiallyExpanded() &&
4752 PackScope.isDeducedFromEarlierParameter()) {
4765 std::optional<unsigned> ArgPosAfterSubstitution =
4766 PackScope.getSavedPackSizeIfAllEqual();
4767 if (!ArgPosAfterSubstitution)
4770 unsigned PackArgEnd = ArgIdx + *ArgPosAfterSubstitution;
4771 for (; ArgIdx < PackArgEnd && ArgIdx < Args.size(); ArgIdx++) {
4772 ParamTypesForArgChecking.push_back(ParamPattern);
4774 DeduceCallArgument(ParamPattern, ArgIdx,
4779 PackScope.nextPackElement();
4786 if (
auto Result = PackScope.finish();
4797 Result = FinishTemplateArgumentDeduction(
4798 FunctionTemplate, Deduced, NumExplicitlySpecified, Specialization, Info,
4799 &OriginalCallArgs, PartialOverloading, PartialOrdering,
4801 ContextRAII SavedContext(*this, CallingCtx);
4802 return CheckNonDependent(ParamTypesForArgChecking);
4810 bool AdjustExceptionSpec) {
4811 if (ArgFunctionType.
isNull())
4812 return ArgFunctionType;
4817 bool Rebuild =
false;
4820 if (EPI.ExtInfo.getCC() != CC) {
4821 EPI.
ExtInfo = EPI.ExtInfo.withCallingConv(CC);
4825 bool NoReturn = FunctionTypeP->getNoReturnAttr();
4826 if (EPI.ExtInfo.getNoReturn() != NoReturn) {
4827 EPI.ExtInfo = EPI.ExtInfo.withNoReturn(NoReturn);
4831 if (AdjustExceptionSpec && (FunctionTypeP->hasExceptionSpec() ||
4833 EPI.ExceptionSpec = FunctionTypeP->getExtProtoInfo().ExceptionSpec;
4838 return ArgFunctionType;
4848 bool IsAddressOfFunction) {
4860 unsigned NumExplicitlySpecified = 0;
4862 if (ExplicitTemplateArgs) {
4865 Result = SubstituteExplicitTemplateArguments(
4866 FunctionTemplate, *ExplicitTemplateArgs, Deduced, ParamTypes,
4867 &FunctionType, Info);
4872 NumExplicitlySpecified = Deduced.size();
4878 if (!IsAddressOfFunction)
4887 Deduced.resize(TemplateParams->
size());
4891 bool HasDeducedReturnType =
false;
4893 Function->getReturnType()->getContainedAutoType()) {
4895 HasDeducedReturnType =
true;
4903 *
this, TemplateParams,
FunctionType, ArgFunctionType, Info, Deduced,
4904 TDF, PartialOrderingKind::None,
false,
4912 Result = FinishTemplateArgumentDeduction(
4913 FunctionTemplate, Deduced, NumExplicitlySpecified, Specialization, Info,
4922 if (HasDeducedReturnType && IsAddressOfFunction &&
4943 if (!IsAddressOfFunction) {
4949 if (HasDeducedReturnType) {
4958 if (!ArgFunctionType.
isNull()) {
4960 SpecializationType, ArgFunctionType)
4962 SpecializationType, ArgFunctionType)) {
4983 bool IsReferenceP =
P->isReferenceType();
4990 P = PRef->getPointeeType();
5000 if (!IsReferenceP) {
5002 P =
P.getUnqualifiedType();
5009 assert(!A->
isReferenceType() &&
"Reference types were handled above");
5014 if (
P->isArrayType())
5019 else if (
P->isFunctionType())
5024 P =
P.getUnqualifiedType();
5046 Deduced.resize(TemplateParams->
size());
5075 ParamType, ObjectType, ObjectClassification,
5076 nullptr, Info, Deduced, OriginalCallArgs,
5083 *
this, TemplateParams,
P, A, Info, Deduced, TDF,
5084 PartialOrderingKind::None,
false,
5095 Result = FinishTemplateArgumentDeduction(
5096 ConversionTemplate, Deduced, 0, ConversionSpecialized, Info,
5097 &OriginalCallArgs, false,
5100 Specialization = cast_or_null<CXXConversionDecl>(ConversionSpecialized);
5109 bool IsAddressOfFunction) {
5112 IsAddressOfFunction);
5116 struct DependentAuto {
bool IsPack; };
5120 class SubstituteDeducedTypeTransform :
5123 bool ReplacementIsPack;
5128 SubstituteDeducedTypeTransform(
Sema &SemaRef, DependentAuto DA)
5130 ReplacementIsPack(DA.IsPack), UseTypeSugar(
true) {}
5132 SubstituteDeducedTypeTransform(
Sema &SemaRef,
QualType Replacement,
5133 bool UseTypeSugar =
true)
5135 Replacement(Replacement), ReplacementIsPack(
false),
5136 UseTypeSugar(UseTypeSugar) {}
5139 assert(isa<TemplateTypeParmType>(Replacement) &&
5140 "unexpected unsugared replacement kind");
5158 return TransformDesugared(TLB, TL);
5160 QualType Result = SemaRef.Context.getAutoType(
5169 QualType TransformDeducedTemplateSpecializationType(
5172 return TransformDesugared(TLB, TL);
5174 QualType Result = SemaRef.Context.getDeducedTemplateSpecializationType(
5176 Replacement, Replacement.isNull());
5194 return inherited::TransformExceptionSpec(
Loc, ESI, Exceptions, Changed);
5202 return TransformType(TLB, TL);
5218 Deduced,
TypeLoc.getNameLoc())));
5219 for (
unsigned I = 0,
C =
TypeLoc.getNumArgs(); I !=
C; ++I)
5225 false, SugaredConverted, CanonicalConverted))
5241 S.
getASTContext(), Concept->getDeclContext(), Concept->getLocation(),
5242 CanonicalConverted));
5249 llvm::raw_string_ostream OS(Buf);
5250 OS <<
"'" << Concept->getName();
5251 if (
TypeLoc.hasExplicitTemplateArgs()) {
5254 Type.getTypeConstraintConcept()->getTemplateParameters());
5258 diag::err_placeholder_constraints_not_satisfied)
5269 bool IgnoreConstraints,
5272 if (
Init->containsErrors())
5285 DependentAuto DependentResult = {
5288 if (!DependentDeduction &&
5290 Init->containsUnexpandedParameterPack())) {
5291 Result = SubstituteDeducedTypeTransform(*
this, DependentResult).Apply(
Type);
5292 assert(!
Result.isNull() &&
"substituting DependentTy can't fail");
5297 auto *String = dyn_cast<StringLiteral>(
Init);
5299 Diag(
Type.getBeginLoc(), diag::ext_c23_auto_non_plain_identifier);
5301 Result = SubstituteDeducedTypeTransform(*
this, DependentResult).Apply(TL);
5302 assert(!
Result.isNull() &&
"substituting DependentTy can't fail");
5308 Diag(
Type.getBeginLoc(), diag::ext_c23_auto_non_plain_identifier);
5311 auto *InitList = dyn_cast<InitListExpr>(
Init);
5313 Diag(
Init->getBeginLoc(), diag::err_auto_init_list_from_c)
5325 if (
Init->isTypeDependent()) {
5327 SubstituteDeducedTypeTransform(*
this, DependentResult).Apply(
Type);
5328 assert(!
Result.isNull() &&
"substituting DependentTy can't fail");
5340 Diag(
Init->getBeginLoc(), diag::err_decltype_auto_initializer_list);
5353 nullptr,
false,
false,
false);
5367 for (
Expr *
Init : InitList->inits()) {
5370 if (isa<DesignatedInitExpr>(
Init))
5373 *
this, TemplateParamsSt.get(), 0, TemplArg,
Init->getType(),
5382 <<
Init->getSourceRange();
5385 return DeductionFailed(TDK);
5390 DeducedFromInitRange =
Init->getSourceRange();
5394 Diag(
Loc, diag::err_auto_bitfield);
5398 SubstituteDeducedTypeTransform(*
this, TemplArg).Apply(
Type);
5399 assert(!FuncParam.
isNull() &&
5400 "substituting template parameter for 'auto' failed");
5402 *
this, TemplateParamsSt.get(), 0, FuncParam,
Init->getType(),
5405 false, 0, 0, FailedTSC);
5407 return DeductionFailed(TDK);
5444 assert((
bool)InitList == OriginalArg.DecomposedParam &&
5445 "decomposed non-init-list in auto deduction?");
5450 return DeductionFailed(TDK);
5460 return SubstituteDeducedTypeTransform(*
this, TypeToReplaceAuto)
5461 .TransformType(TypeWithAuto);
5467 return SubstituteDeducedTypeTransform(*
this, TypeToReplaceAuto)
5468 .TransformType(TypeWithAuto);
5472 return SubstituteDeducedTypeTransform(*
this, DependentAuto{
false})
5473 .TransformType(TypeWithAuto);
5478 return SubstituteDeducedTypeTransform(*
this, DependentAuto{
false})
5479 .TransformType(TypeWithAuto);
5484 return SubstituteDeducedTypeTransform(*
this, TypeToReplaceAuto,
5486 .TransformType(TypeWithAuto);
5491 return SubstituteDeducedTypeTransform(*
this, TypeToReplaceAuto,
5493 .TransformType(TypeWithAuto);
5498 if (isa<InitListExpr>(
Init))
5501 ? diag::err_init_capture_deduction_failure_from_init_list
5502 : diag::err_auto_var_deduction_failure_from_init_list)
5506 VDecl->
isInitCapture() ? diag::err_init_capture_deduction_failure
5507 : diag::err_auto_var_deduction_failure)
5509 <<
Init->getSourceRange();
5541 "failed to deduce lambda return type");
5568 Diag(
Loc, diag::err_auto_fn_used_before_defined) << FD;
5572 return StillUndeduced;
5616 "expected a member function with no explicit object parameter");
5632 bool IsIncompleteSubstitution =
false;
5638 if (InstP.
isNull() && !IsIncompleteSubstitution)
5640 if (!CheckConsistency)
5642 if (IsIncompleteSubstitution)
5647 if (
auto *PA = dyn_cast<PackExpansionType>(A);
5648 PA && !isa<PackExpansionType>(InstP))
5649 A = PA->getPattern();
5671 bool IsIncomplete =
false;
5674 S, FTD,
true, Deduced, Info, SugaredBuilder,
5675 CanonicalBuilder,
true,
5687 Info.
reset(SugaredDeducedArgumentList, CanonicalDeducedArgumentList);
5712 assert(Proto1 && Proto2 &&
"Function templates must have prototypes");
5728 Proto1->
isVariadic() == Proto2->isVariadic() &&
5729 "shouldn't partial order functions with different qualifiers in a "
5730 "context where the function type is used");
5732 assert(Args1.empty() && Args2.empty() &&
5733 "Only call context should have arguments");
5735 Args2 = Proto2->getParamTypes();
5742 bool HasDeducedAnyParamFromReturnType =
false;
5745 S, TemplateParams, Proto2->getReturnType(), Proto1->
getReturnType(),
5746 Info, Deduced,
TDF_None, PartialOrderingKind::Call,
5748 &HasDeducedAnyParamFromReturnType) !=
5753 llvm::SmallBitVector HasDeducedParam;
5755 HasDeducedParam.resize(Args2.size());
5757 TDF_None, PartialOrderingKind::Call,
5759 &HasDeducedParam) !=
5771 bool AtLeastAsSpecialized;
5773 AtLeastAsSpecialized =
5774 ::FinishTemplateArgumentDeduction(
5775 S, FT2, Deduced, Info,
5776 [&](Sema &S, FunctionTemplateDecl *FTD,
5777 ArrayRef<TemplateArgument> DeducedArgs) {
5782 if (TPOC != TPOC_Call) {
5783 if (auto TDR = ::CheckDeductionConsistency(
5784 S, FTD, -1, Proto2->getReturnType(),
5785 Proto1->getReturnType(), DeducedArgs,
5786 HasDeducedAnyParamFromReturnType);
5787 TDR != TemplateDeductionResult::Success)
5791 if (TPOC == TPOC_Conversion)
5792 return TemplateDeductionResult::Success;
5794 return ::DeduceForEachType(
5795 S, TemplateParams, Args2, Args1, Info, Deduced,
5796 PartialOrderingKind::Call, true,
5797 [&](Sema &S, TemplateParameterList *, int ParamIdx,
5798 int ArgIdx, QualType P, QualType A,
5799 TemplateDeductionInfo &Info,
5800 SmallVectorImpl<DeducedTemplateArgument> &Deduced,
5801 PartialOrderingKind) {
5803 ArgIdx -= Args1Offset;
5804 return ::CheckDeductionConsistency(
5805 S, FTD, ArgIdx, P, A, DeducedArgs,
5806 HasDeducedParam[ParamIdx]);
5810 if (!AtLeastAsSpecialized)
5819 unsigned ArgIdx = 0, NumArgs = Deduced.size();
5820 for (; ArgIdx != NumArgs; ++ArgIdx)
5821 if (Deduced[ArgIdx].isNull())
5824 if (ArgIdx == NumArgs) {
5831 llvm::SmallBitVector UsedParameters(TemplateParams->size());
5834 for (
unsigned I = 0, N = Args2.size(); I != N; ++I)
5836 TemplateParams->getDepth(), UsedParameters);
5842 TemplateParams->getDepth(), UsedParameters);
5868 false, TemplateParams->getDepth(), UsedParameters);
5872 for (; ArgIdx != NumArgs; ++ArgIdx)
5875 if (Deduced[ArgIdx].isNull() && UsedParameters[ArgIdx])
5889 bool ShouldConvert1 =
false;
5890 bool ShouldConvert2 =
false;
5891 bool Args1Offset =
false;
5892 bool Args2Offset =
false;
5903 const CXXMethodDecl *Method1 = dyn_cast<CXXMethodDecl>(FD1);
5904 const CXXMethodDecl *Method2 = dyn_cast<CXXMethodDecl>(FD2);
5915 bool NonStaticMethod1 = Method1 && !Method1->isStatic(),
5916 NonStaticMethod2 = Method2 && !Method2->
isStatic();
5919 Params2Begin = Proto2->param_type_begin();
5921 size_t NumComparedArguments = NumCallArguments1;
5924 (NonStaticMethod1 && NonStaticMethod2) ||
5925 (OO !=
OO_None && OO != OO_Call && OO != OO_Subscript)) {
5927 NonStaticMethod1 && !Method1->hasCXXExplicitFunctionObjectParameter();
5930 NumComparedArguments += 1;
5932 if (ShouldConvert1) {
5936 : Proto2->param_type_begin()[0]->isRValueReferenceType();
5939 RawObj1Ty, IsRValRef2);
5940 Args1.push_back(Obj1Ty);
5943 if (ShouldConvert2) {
5946 ? Method1->getRefQualifier() ==
RQ_RValue
5950 RawObj2Ty, IsRValRef1);
5951 Args2.push_back(Obj2Ty);
5955 if (NonStaticMethod1 && Method1->hasCXXExplicitFunctionObjectParameter())
5960 Args1.insert(Args1.end(), Params1Begin, Proto1->
param_type_end());
5961 Args2.insert(Args2.end(), Params2Begin, Proto2->param_type_end());
5966 Args1.resize(std::min(Args1.size(), NumComparedArguments));
5967 Args2.resize(std::min(Args2.size(), NumComparedArguments));
5970 std::reverse(Args2.begin(), Args2.end());
5972 assert(!
Reversed &&
"Only call context could have reversed arguments");
5975 Args2, Args2Offset);
5977 Args1, Args1Offset);
5981 if (Better1 != Better2)
5982 return Better1 ? FT1 : FT2;
5984 if (!Better1 && !Better2)
5993 Param1.reserve(FD1->
param_size() + ShouldConvert1);
5995 Param1.push_back(Obj1Ty);
5997 Param1.push_back(
P->getType());
6000 Param2.reserve(FD2->
param_size() + ShouldConvert2);
6002 Param2.push_back(Obj2Ty);
6004 Param2.push_back(
P->getType());
6006 unsigned NumParams1 = Param1.size();
6007 unsigned NumParams2 = Param2.size();
6013 if (Variadic1 != Variadic2) {
6014 if (Variadic1 && NumParams1 > NumParams2)
6016 if (Variadic2 && NumParams2 > NumParams1)
6022 for (
int i = 0, e = std::min(NumParams1, NumParams2); i < e; ++i) {
6023 QualType T1 = Param1[i].getCanonicalType();
6024 QualType T2 = Param2[i].getCanonicalType();
6025 auto *TST1 = dyn_cast<TemplateSpecializationType>(T1);
6026 auto *TST2 = dyn_cast<TemplateSpecializationType>(T2);
6031 assert(TST1->template_arguments().size() ==
6032 TST2->template_arguments().size());
6037 bool IsPackExpansion1 =
6039 bool IsPackExpansion2 =
6041 if (PackSize1 != PackSize2 && IsPackExpansion1 != IsPackExpansion2) {
6042 if (PackSize1 > PackSize2 && IsPackExpansion1)
6044 if (PackSize1 < PackSize2 && IsPackExpansion2)
6066 if (TPL1->
size() != TPL2->
size() || NumParams1 != NumParams2)
6082 for (
unsigned i = 0; i < NumParams1; ++i)
6098 bool AtLeastAsConstrained1, AtLeastAsConstrained2;
6103 if (AtLeastAsConstrained1 == AtLeastAsConstrained2)
6105 return AtLeastAsConstrained1 ? FT1 : FT2;
6113 bool Complain,
QualType TargetType) {
6114 if (SpecBegin == SpecEnd) {
6122 if (SpecBegin + 1 == SpecEnd)
6129 = cast<FunctionDecl>(*Best)->getPrimaryTemplate();
6130 assert(BestTemplate &&
"Not a function template specialization?");
6133 = cast<FunctionDecl>(*I)->getPrimaryTemplate();
6134 assert(Challenger &&
"Not a function template specialization?");
6139 BestTemplate = Challenger;
6145 bool Ambiguous =
false;
6148 = cast<FunctionDecl>(*I)->getPrimaryTemplate();
6170 const auto *FD = cast<FunctionDecl>(*I);
6172 FD->getPrimaryTemplate()->getTemplateParameters(),
6173 *FD->getTemplateSpecializationArgs());
6174 if (!TargetType.
isNull())
6176 Diag((*I)->getLocation(), PD);
6186 "not for function templates");
6188 isa<CXXConversionDecl>(FD1));
6190 isa<CXXConversionDecl>(FD2));
6203 bool AtLeastAsConstrained1, AtLeastAsConstrained2;
6208 if (AtLeastAsConstrained1 == AtLeastAsConstrained2)
6210 return AtLeastAsConstrained1 ? FD1 : FD2;
6220template<
typename TemplateLikeDecl>
6222 TemplateLikeDecl *P2,
6251 Deduced.resize(P2->getTemplateParameters()->size());
6253 S, P2->getTemplateParameters(), T2, T1, Info, Deduced,
TDF_None,
6254 PartialOrderingKind::Call,
false,
6265 const auto *TST1 = cast<TemplateSpecializationType>(T1);
6271 Result = ::FinishTemplateArgumentDeduction(
6272 S, P2, true, TST1->template_arguments(), Deduced,
6289 template <
typename T1,
typename T2,
6290 std::enable_if_t<std::is_same_v<T1, T2>,
bool> =
true>
6291 T2 *operator()(T1 *, T2 *P2) {
6294 template <
typename T1,
typename T2,
6295 std::enable_if_t<!std::is_same_v<T1, T2>,
bool> =
true>
6296 T1 *operator()(T1 *, T2 *) {
6302struct TemplateArgumentListAreEqual {
6304 TemplateArgumentListAreEqual(
ASTContext &Ctx) : Ctx(Ctx) {}
6306 template <
typename T1,
typename T2,
6307 std::enable_if_t<std::is_same_v<T1, T2>,
bool> =
true>
6308 bool operator()(T1 *PS1, T2 *PS2) {
6310 Args2 = PS2->getTemplateArgs().asArray();
6312 for (
unsigned I = 0,
E = Args1.size(); I <
E; ++I) {
6316 llvm::FoldingSetNodeID IDA, IDB;
6317 Args1[I].Profile(IDA, Ctx);
6318 Args2[I].Profile(IDB, Ctx);
6325 template <
typename T1,
typename T2,
6326 std::enable_if_t<!std::is_same_v<T1, T2>,
bool> =
true>
6327 bool operator()(T1 *Spec, T2 *Primary) {
6329 Args2 = Primary->getInjectedTemplateArgs(Ctx);
6331 for (
unsigned I = 0,
E = Args1.size(); I <
E; ++I) {
6335 llvm::FoldingSetNodeID IDA, IDB;
6336 Args1[I].Profile(IDA, Ctx);
6370template <
typename TemplateLikeDecl,
typename PrimaryDel>
6371static TemplateLikeDecl *
6374 constexpr bool IsMoreSpecialThanPrimaryCheck =
6375 !std::is_same_v<TemplateLikeDecl, PrimaryDel>;
6378 if (IsMoreSpecialThanPrimaryCheck && !Better1)
6382 if (IsMoreSpecialThanPrimaryCheck && !Better2)
6388 if (Better1 != Better2)
6389 return Better1 ? P1 : GetP2()(P1, P2);
6391 if (!Better1 && !Better2)
6396 auto *TST1 = cast<TemplateSpecializationType>(T1);
6397 auto *TST2 = cast<TemplateSpecializationType>(T2);
6400 assert(TST1->template_arguments().size() ==
6401 TST2->template_arguments().size());
6406 bool IsPackExpansion1 =
6408 bool IsPackExpansion2 =
6410 if (PackSize1 != PackSize2 && IsPackExpansion1 != IsPackExpansion2) {
6411 if (PackSize1 > PackSize2 && IsPackExpansion1)
6412 return GetP2()(P1, P2);
6413 if (PackSize1 < PackSize2 && IsPackExpansion2)
6442 if (!TemplateArgumentListAreEqual(S.
getASTContext())(P1, P2))
6446 P1->getAssociatedConstraints(AC1);
6447 P2->getAssociatedConstraints(AC2);
6448 bool AtLeastAsConstrained1, AtLeastAsConstrained2;
6450 (IsMoreSpecialThanPrimaryCheck && !AtLeastAsConstrained1))
6454 if (AtLeastAsConstrained1 == AtLeastAsConstrained2)
6456 return AtLeastAsConstrained1 ? P1 : GetP2()(P1, P2);
6491 "the partial specializations being compared should specialize"
6492 " the same template.");
6555 for (
unsigned I = 0, N =
P->size(); I != N; ++I) {
6564 Arg,
QualType(),
P->getParam(I)->getLocation()));
6573 AArg, ArgLoc, PArgList, DefaultArgs,
false, PArgs, CanonicalPArgs,
6576 true, MatchedPackOnParmToNonPackOnArg))
6583 Deduced.resize(A->
size());
6597 *
this, A, AArgs, PArgs, Info, Deduced,
6602 if (MatchedPackOnParmToNonPackOnArg &&
6604 *MatchedPackOnParmToNonPackOnArg =
true;
6608 Diag(AArg->
getLocation(), diag::err_template_param_list_different_arity)
6609 << (A->
size() >
P->size()) <<
true
6618 diag::err_inconsistent_deduction)
6639 llvm_unreachable(
"Unexpected Result");
6646 TDK = ::FinishTemplateArgumentDeduction(
6647 *this, AArg, true, PArgs, Deduced, Info);
6656 llvm_unreachable(
"Unexpected NonDeducedMismatch");
6679 llvm_unreachable(
"Unexpected Result");
6681 llvm_unreachable(
"Unexpected TDK");
6686 llvm::SmallBitVector &
Used;
6689 MarkUsedTemplateParameterVisitor(llvm::SmallBitVector &
Used,
6694 if (
T->getDepth() == Depth)
6695 Used[
T->getIndex()] =
true;
6699 bool TraverseTemplateName(
TemplateName Template)
override {
6700 if (
auto *TTP = llvm::dyn_cast_or_null<TemplateTemplateParmDecl>(
6702 if (TTP->getDepth() == Depth)
6703 Used[TTP->getIndex()] =
true;
6709 if (
auto *NTTP = dyn_cast<NonTypeTemplateParmDecl>(
E->getDecl()))
6710 if (NTTP->getDepth() == Depth)
6711 Used[NTTP->getIndex()] =
true;
6724 llvm::SmallBitVector &
Used) {
6726 MarkUsedTemplateParameterVisitor(
Used, Depth)
6727 .TraverseStmt(
const_cast<Expr *
>(
E));
6733 E = Expansion->getPattern();
6755 llvm::SmallBitVector &
Used) {
6762 OnlyDeduced, Depth,
Used);
6772 llvm::SmallBitVector &
Used) {
6773 if (
TemplateDecl *Template = Name.getAsTemplateDecl()) {
6775 = dyn_cast<TemplateTemplateParmDecl>(Template)) {
6776 if (TTP->getDepth() == Depth)
6777 Used[TTP->getIndex()] =
true;
6796 llvm::SmallBitVector &
Used) {
6814 case Type::BlockPointer:
6822 case Type::LValueReference:
6823 case Type::RValueReference:
6831 case Type::MemberPointer: {
6836 OnlyDeduced, Depth,
Used);
6840 case Type::DependentSizedArray:
6842 cast<DependentSizedArrayType>(
T)->getSizeExpr(),
6843 OnlyDeduced, Depth,
Used);
6847 case Type::ConstantArray:
6848 case Type::IncompleteArray:
6849 case Type::ArrayParameter:
6851 cast<ArrayType>(
T)->getElementType(),
6852 OnlyDeduced, Depth,
Used);
6855 case Type::ExtVector:
6857 cast<VectorType>(
T)->getElementType(),
6858 OnlyDeduced, Depth,
Used);
6861 case Type::DependentVector: {
6862 const auto *VecType = cast<DependentVectorType>(
T);
6869 case Type::DependentSizedExtVector: {
6871 = cast<DependentSizedExtVectorType>(
T);
6879 case Type::DependentAddressSpace: {
6881 cast<DependentAddressSpaceType>(
T);
6883 OnlyDeduced, Depth,
Used);
6886 OnlyDeduced, Depth,
Used);
6890 case Type::ConstantMatrix: {
6897 case Type::DependentSizedMatrix: {
6908 case Type::FunctionProto: {
6912 for (
unsigned I = 0, N = Proto->
getNumParams(); I != N; ++I) {
6917 if (!OnlyDeduced || I + 1 == N ||
6935 case Type::TemplateTypeParm: {
6942 case Type::SubstTemplateTypeParmPack: {
6944 = cast<SubstTemplateTypeParmPackType>(
T);
6948 OnlyDeduced, Depth,
Used);
6952 case Type::InjectedClassName:
6953 T = cast<InjectedClassNameType>(
T)->getInjectedSpecializationType();
6956 case Type::TemplateSpecialization: {
6958 = cast<TemplateSpecializationType>(
T);
6978 cast<ComplexType>(
T)->getElementType(),
6979 OnlyDeduced, Depth,
Used);
6985 cast<AtomicType>(
T)->getValueType(),
6986 OnlyDeduced, Depth,
Used);
6989 case Type::DependentName:
6992 cast<DependentNameType>(
T)->getQualifier(),
6993 OnlyDeduced, Depth,
Used);
6996 case Type::DependentTemplateSpecialization: {
7010 = cast<DependentTemplateSpecializationType>(
T);
7013 OnlyDeduced, Depth,
Used);
7023 OnlyDeduced, Depth,
Used);
7026 case Type::TypeOfExpr:
7029 cast<TypeOfExprType>(
T)->getUnderlyingExpr(),
7030 OnlyDeduced, Depth,
Used);
7033 case Type::Decltype:
7036 cast<DecltypeType>(
T)->getUnderlyingExpr(),
7037 OnlyDeduced, Depth,
Used);
7040 case Type::PackIndexing:
7043 OnlyDeduced, Depth,
Used);
7045 OnlyDeduced, Depth,
Used);
7049 case Type::UnaryTransform:
7053 OnlyDeduced, Depth,
Used);
7056 case Type::PackExpansion:
7058 cast<PackExpansionType>(
T)->getPattern(),
7059 OnlyDeduced, Depth,
Used);
7063 case Type::DeducedTemplateSpecialization:
7065 cast<DeducedType>(
T)->getDeducedType(),
7066 OnlyDeduced, Depth,
Used);
7068 case Type::DependentBitInt:
7070 cast<DependentBitIntType>(
T)->getNumBitsExpr(),
7071 OnlyDeduced, Depth,
Used);
7074 case Type::HLSLAttributedResource:
7076 Ctx, cast<HLSLAttributedResourceType>(
T)->getWrappedType(), OnlyDeduced,
7078 if (cast<HLSLAttributedResourceType>(
T)->hasContainedType())
7080 Ctx, cast<HLSLAttributedResourceType>(
T)->getContainedType(),
7081 OnlyDeduced, Depth,
Used);
7086 case Type::VariableArray:
7087 case Type::FunctionNoProto:
7090 case Type::ObjCInterface:
7091 case Type::ObjCObject:
7092 case Type::ObjCObjectPointer:
7093 case Type::UnresolvedUsing:
7096#define TYPE(Class, Base)
7097#define ABSTRACT_TYPE(Class, Base)
7098#define DEPENDENT_TYPE(Class, Base)
7099#define NON_CANONICAL_TYPE(Class, Base) case Type::Class:
7100#include "clang/AST/TypeNodes.inc"
7112 llvm::SmallBitVector &
Used) {
7130 OnlyDeduced, Depth,
Used);
7148 llvm::SmallBitVector &
Used) {
7154 bool OnlyDeduced,
unsigned Depth,
7155 llvm::SmallBitVector &
Used) {
7164 for (
unsigned I = 0, N = TemplateArgs.
size(); I != N; ++I)
7171 llvm::SmallBitVector &Deduced) {
7175 Deduced.resize(TemplateParams->
size());
7178 for (
unsigned I = 0, N =
Function->getNumParams(); I != N; ++I)
7180 true, TemplateParams->
getDepth(), Deduced);
7191 llvm::SmallBitVector Deduced(TemplateParams->
size());
7195 return Deduced.any();
Defines the clang::ASTContext interface.
This file provides some common utility functions for processing Lambda related AST Constructs.
Provides definitions for the various language-specific address spaces.
static Decl::Kind getKind(const Decl *D)
Defines the C++ Decl subclasses, other than those for templates (found in DeclTemplate....
Defines the C++ template declaration subclasses.
Defines the ExceptionSpecificationType enumeration and various utility functions.
Defines the clang::Expr interface and subclasses for C++ expressions.
llvm::DenseSet< const void * > Visited
Forward-declares and imports various common LLVM datatypes that clang wants to use unqualified.
Defines the clang::LangOptions interface.
Implements a partial diagnostic that can be emitted anwyhere in a DiagnosticBuilder stream.
static QualType getUnderlyingType(const SubRegion *R)
static TemplateDeductionResult 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 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 ConvertDeducedTemplateArgument(Sema &S, NamedDecl *Param, DeducedTemplateArgument Arg, NamedDecl *Template, TemplateDeductionInfo &Info, bool IsDeduced, bool PartialOrdering, SmallVectorImpl< TemplateArgument > &SugaredOutput, SmallVectorImpl< TemplateArgument > &CanonicalOutput)
Convert the given deduced template argument and add it to the set of fully-converted template argumen...
static bool DeducedArgsNeedReplacement(TemplateDeclT *Template)
static TemplateDeductionResult CheckDeductionConsistency(Sema &S, FunctionTemplateDecl *FTD, int ArgIdx, QualType P, QualType A, ArrayRef< TemplateArgument > DeducedArgs, bool CheckConsistency)
static TemplateDeductionResult ConvertDeducedTemplateArguments(Sema &S, TemplateDeclT *Template, bool IsDeduced, SmallVectorImpl< DeducedTemplateArgument > &Deduced, TemplateDeductionInfo &Info, SmallVectorImpl< TemplateArgument > &SugaredBuilder, SmallVectorImpl< TemplateArgument > &CanonicalBuilder, bool PartialOrdering, LocalInstantiationScope *CurrentInstantiationScope, unsigned NumAlreadyConverted, bool *IsIncomplete)
static QualType ResolveOverloadForDeduction(Sema &S, TemplateParameterList *TemplateParams, Expr *Arg, QualType ParamType, bool ParamWasReference, TemplateSpecCandidateSet *FailedTSC=nullptr)
Apply the deduction rules for overload sets.
static bool IsPossiblyOpaquelyQualifiedType(QualType T)
Determines whether the given type is an opaque type that might be more qualified when instantiated.
static 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.
FriendObjectKind getFriendObjectKind() const
Determines whether this declaration is the object of a friend declaration and, if so,...
bool isParameterPack() const
Whether this declaration is a parameter pack.
@ FOK_None
Not a friend object.
bool isInvalidDecl() const
SourceLocation getLocation() const
bool isTemplateParameterPack() const
isTemplateParameter - Determines whether this declaration is a template parameter pack.
DeclContext * getDeclContext()
DeclContext * getLexicalDeclContext()
getLexicalDeclContext - The declaration context where this Decl was lexically declared (LexicalDC).
virtual Decl * getCanonicalDecl()
Retrieves the "canonical" declaration of the given declaration.
virtual SourceRange getSourceRange() const LLVM_READONLY
Source range that this declaration covers.
Captures a template argument whose value has been deduced via c++ template argument deduction.
void setDeducedFromArrayBound(bool Deduced)
Specify whether the given non-type template argument was deduced from an array bound.
bool wasDeducedFromArrayBound() const
For a non-type template argument, determine whether the template argument was deduced from an array b...
TemplateName getTemplateName() const
Retrieve the name of the template that we are deducing.
Common base class for placeholders for types that get replaced by placeholder type deduction: C++11 a...
Represents an extended address space qualifier where the input address space value is dependent.
Expr * getAddrSpaceExpr() const
QualType getPointeeType() const
Represents an extended vector type where either the type or size is dependent.
Expr * getSizeExpr() const
QualType getElementType() const
Represents a matrix type where the type and the number of rows and columns is dependent on a template...
Expr * getColumnExpr() const
Expr * getRowExpr() const
Represents a dependent template name that cannot be resolved prior to template instantiation.
Represents a template specialization type whose template cannot be resolved, e.g.
ArrayRef< TemplateArgument > template_arguments() const
NestedNameSpecifier * getQualifier() const
Represents a vector type where either the type or size is dependent.
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
bool isDefined(const FunctionDecl *&Definition, bool CheckForPendingFriendDefinition=false) const
Returns true if the function has a definition that does not need to be instantiated.
Represents a prototype with parameter type info, e.g.
param_type_iterator param_type_begin() const
const ExtParameterInfo * getExtParameterInfosOrNull() const
Return a pointer to the beginning of the array of extra parameter information, if present,...
unsigned getNumParams() const
bool hasTrailingReturn() const
Whether this function prototype has a trailing return type.
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 CheckTemplateArgument(NamedDecl *Param, TemplateArgumentLoc &Arg, NamedDecl *Template, SourceLocation TemplateLoc, SourceLocation RAngleLoc, unsigned ArgumentPackIndex, SmallVectorImpl< TemplateArgument > &SugaredConverted, SmallVectorImpl< TemplateArgument > &CanonicalConverted, CheckTemplateArgumentKind CTAK, bool PartialOrdering, bool *MatchedPackOnParmToNonPackOnArg)
Check that the given template argument corresponds to the given template parameter.
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...
bool CheckTemplateArgumentList(TemplateDecl *Template, SourceLocation TemplateLoc, TemplateArgumentListInfo &TemplateArgs, const DefaultArguments &DefaultArgs, bool PartialTemplateArgs, SmallVectorImpl< TemplateArgument > &SugaredConverted, SmallVectorImpl< TemplateArgument > &CanonicalConverted, bool UpdateArgsWithConversions=true, bool *ConstraintsNotSatisfied=nullptr, bool PartialOrderingTTP=false, bool *MatchedPackOnParmToNonPackOnArg=nullptr)
Check that the given template arguments can be provided to the given template, converting the argumen...
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 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.
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.
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
@ 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.