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);
160 bool OnlyDeduced,
unsigned Depth,
161 llvm::SmallBitVector &
Used);
164 bool OnlyDeduced,
unsigned Level,
165 llvm::SmallBitVector &Deduced);
175 if (
const auto *IC = dyn_cast<ImplicitCastExpr>(
E))
176 E = IC->getSubExpr();
177 else if (
const auto *CE = dyn_cast<ConstantExpr>(
E))
178 E = CE->getSubExpr();
179 else if (
const auto *Subst = dyn_cast<SubstNonTypeTemplateParmExpr>(
E))
180 E = Subst->getReplacement();
181 else if (
const auto *CCE = dyn_cast<CXXConstructExpr>(
E)) {
183 if (CCE->getParenOrBraceRange().isValid())
186 assert(CCE->getNumArgs() >= 1 &&
"implicit construct expr should have 1 arg");
192 if (
const auto *DRE = dyn_cast<DeclRefExpr>(
E))
193 if (
const auto *NTTP = dyn_cast<NonTypeTemplateParmDecl>(DRE->getDecl()))
194 if (NTTP->getDepth() == Depth)
209 X = NX->getUnderlyingDecl();
210 if (
NamedDecl *NY = dyn_cast<NamedDecl>(Y))
211 Y = NY->getUnderlyingDecl();
224 bool AggregateCandidateDeduction =
false) {
237 QualType XType =
X.getNonTypeTemplateArgumentType();
245 switch (
X.getKind()) {
247 llvm_unreachable(
"Non-deduced template arguments handled above");
254 X.wasDeducedFromArrayBound() ||
260 return X.wasDeducedFromArrayBound() ? Y :
X;
274 return X.wasDeducedFromArrayBound() ? Y :
X;
283 X.structurallyEquals(Y)))
311 llvm::FoldingSetNodeID ID1, ID2;
312 X.getAsExpr()->Profile(ID1, Context,
true);
315 return X.wasDeducedFromArrayBound() ? Y :
X;
322 assert(!
X.wasDeducedFromArrayBound());
335 X.getParamTypeForDecl());
372 (!AggregateCandidateDeduction &&
X.pack_size() != Y.
pack_size()))
384 if (Merged.isNull() && !(XA->isNull() && YA->isNull()))
386 NewPack.push_back(Merged);
389 NewPack.push_back(*XA);
399 llvm_unreachable(
"Invalid TemplateArgument Kind!");
412 bool *HasDeducedAnyParam) {
414 "deducing non-type template argument with wrong depth");
418 if (Result.isNull()) {
422 return TemplateDeductionResult::Inconsistent;
427 return TemplateDeductionResult::Success;
434 return TemplateDeductionResult::Success;
439 if (
auto *Expansion = dyn_cast<PackExpansionType>(ParamType))
440 ParamType = Expansion->getPattern();
454 S, TemplateParams, ParamType, ValueType, Info, Deduced,
468 bool *HasDeducedAnyParam) {
470 S, TemplateParams, NTTP,
472 DeducedFromArrayBound),
484 bool *HasDeducedAnyParam) {
506 bool *HasDeducedAnyParam) {
522 bool *HasDeducedAnyParam) {
534 bool *HasDeducedAnyParam) {
539 return TemplateDeductionResult::Success;
542 if (
auto *TempParam = dyn_cast<TemplateTemplateParmDecl>(ParamDecl)) {
545 return TemplateDeductionResult::Success;
549 unsigned StartPos = 0;
566 Arg, {StartPos, DefaultArguments.drop_front(StartPos)}))
570 S.
Context, Deduced[TempParam->getIndex()], NewDeduced);
571 if (Result.isNull()) {
572 Info.
Param = TempParam;
573 Info.
FirstArg = Deduced[TempParam->getIndex()];
575 return TemplateDeductionResult::Inconsistent;
578 Deduced[TempParam->getIndex()] = Result;
579 if (HasDeducedAnyParam)
580 *HasDeducedAnyParam =
true;
581 return TemplateDeductionResult::Success;
587 return TemplateDeductionResult::Success;
592 return TemplateDeductionResult::NonDeducedMismatch;
618 assert(TST &&
"Expected a TemplateSpecializationType");
630 bool *HasDeducedAnyParam) {
633 UP = IP->getInjectedSpecializationType();
641 return TemplateDeductionResult::Success;
648 ->template_arguments();
651 std::optional<NestedNameSpecifier *> NNS;
654 NNS = Elaborated->getQualifier();
656 UA = Injected->getInjectedSpecializationType();
667 return TemplateDeductionResult::Success;
674 ->template_arguments();
681 Result != TemplateDeductionResult::Success)
688 S, TemplateParams, PResolved, AResolved, Info, Deduced,
698 RA ? dyn_cast<ClassTemplateSpecializationDecl>(RA->getDecl()) :
nullptr;
702 return TemplateDeductionResult::NonDeducedMismatch;
708 *NNS,
false,
TemplateName(SA->getSpecializedTemplate()));
712 S, TemplateParams, TNP, TNA, Info,
714 Deduced, HasDeducedAnyParam);
715 Result != TemplateDeductionResult::Success)
720 SA->getTemplateArgs().asArray(), Info, Deduced,
730 case Type::TypeOfExpr:
732 case Type::DependentName:
734 case Type::PackIndexing:
735 case Type::UnresolvedUsing:
736 case Type::TemplateTypeParm:
740 case Type::ConstantArray:
741 case Type::IncompleteArray:
742 case Type::VariableArray:
743 case Type::DependentSizedArray:
745 cast<ArrayType>(
T)->getElementType().getTypePtr());
794class PackDeductionScope {
802 bool DeducePackIfNotAlreadyDeduced =
false,
803 bool FinishingDeduction =
false)
804 : S(S), TemplateParams(TemplateParams), Deduced(Deduced), Info(Info),
805 DeducePackIfNotAlreadyDeduced(DeducePackIfNotAlreadyDeduced),
806 FinishingDeduction(FinishingDeduction) {
807 unsigned NumNamedPacks = addPacks(Pattern);
808 finishConstruction(NumNamedPacks);
815 : S(S), TemplateParams(TemplateParams), Deduced(Deduced), Info(Info) {
817 finishConstruction(1);
821 void addPack(
unsigned Index) {
824 DeducedFromEarlierParameter = !Deduced[Index].isNull();
826 if (!FinishingDeduction) {
827 Pack.Saved = Deduced[Index];
834 if (std::optional<unsigned> ExpandedPackExpansions =
836 FixedNumExpansions = ExpandedPackExpansions;
838 Packs.push_back(Pack);
844 llvm::SmallBitVector SawIndices(TemplateParams->size());
847 auto AddPack = [&](
unsigned Index) {
848 if (SawIndices[Index])
850 SawIndices[Index] =
true;
857 if (
auto *NTTP = dyn_cast<NonTypeTemplateParmDecl>(
858 TemplateParams->getParam(Index))) {
859 if (!NTTP->isExpandedParameterPack())
862 if (
auto *Expansion = dyn_cast<PackExpansionType>(
864 ExtraDeductions.push_back(Expansion->getPattern());
873 for (
unsigned I = 0, N = Unexpanded.size(); I != N; ++I) {
874 unsigned Depth, Index;
876 if (Depth == Info.getDeducedDepth())
883 assert(!Packs.empty() &&
"Pack expansion without unexpanded packs?");
885 unsigned NumNamedPacks = Packs.size();
889 while (!ExtraDeductions.empty())
890 Collect(ExtraDeductions.pop_back_val());
892 return NumNamedPacks;
895 void finishConstruction(
unsigned NumNamedPacks) {
898 unsigned NumPartialPackArgs = 0;
899 std::pair<unsigned, unsigned> PartialPackDepthIndex(-1u, -1u);
901 if (
auto *Partial =
Scope->getPartiallySubstitutedPack(
902 &PartialPackArgs, &NumPartialPackArgs))
908 bool IsExpanded =
true;
909 for (
unsigned I = 0; I != NumNamedPacks; ++I) {
910 if (Packs[I].Index >= Info.getNumExplicitArgs()) {
912 IsPartiallyExpanded =
false;
915 if (PartialPackDepthIndex ==
916 std::make_pair(Info.getDeducedDepth(), Packs[I].Index)) {
917 IsPartiallyExpanded =
true;
925 if (IsPartiallyExpanded)
926 PackElements += NumPartialPackArgs;
927 else if (IsExpanded && FixedNumExpansions)
928 PackElements += *FixedNumExpansions;
930 for (
auto &Pack : Packs) {
931 if (Info.PendingDeducedPacks.size() > Pack.Index)
932 Pack.Outer = Info.PendingDeducedPacks[Pack.Index];
934 Info.PendingDeducedPacks.resize(Pack.Index + 1);
935 Info.PendingDeducedPacks[Pack.Index] = &Pack;
937 if (PartialPackDepthIndex ==
938 std::make_pair(Info.getDeducedDepth(), Pack.Index)) {
939 Pack.New.append(PartialPackArgs, PartialPackArgs + NumPartialPackArgs);
948 if (!FinishingDeduction && !IsPartiallyExpanded)
949 Deduced[Pack.Index] = Pack.New[PackElements];
955 ~PackDeductionScope() {
956 for (
auto &Pack : Packs)
957 Info.PendingDeducedPacks[Pack.Index] = Pack.Outer;
961 std::optional<unsigned> getSavedPackSizeIfAllEqual()
const {
962 unsigned PackSize = Packs[0].Saved.pack_size();
964 if (std::all_of(Packs.begin() + 1, Packs.end(), [&PackSize](
const auto &
P) {
965 return P.Saved.pack_size() == PackSize;
973 bool isDeducedFromEarlierParameter()
const {
974 return DeducedFromEarlierParameter;
979 bool isPartiallyExpanded() {
return IsPartiallyExpanded; }
984 bool hasFixedArity() {
return FixedNumExpansions.has_value(); }
989 bool hasNextElement() {
990 return !FixedNumExpansions || *FixedNumExpansions > PackElements;
994 void nextPackElement() {
998 if (!FinishingDeduction) {
999 for (
auto &Pack : Packs) {
1001 if (!Pack.New.empty() || !DeducedArg.
isNull()) {
1002 while (Pack.New.size() < PackElements)
1004 if (Pack.New.size() == PackElements)
1005 Pack.New.push_back(DeducedArg);
1007 Pack.New[PackElements] = DeducedArg;
1008 DeducedArg = Pack.New.size() > PackElements + 1
1009 ? Pack.New[PackElements + 1]
1021 if (FinishingDeduction)
1022 return TemplateDeductionResult::Success;
1025 for (
auto &Pack : Packs) {
1027 if (!FinishingDeduction)
1028 Deduced[Pack.Index] = Pack.Saved;
1043 Pack.New.resize(PackElements);
1047 if (Pack.New.empty()) {
1053 std::copy(Pack.New.begin(), Pack.New.end(), ArgumentPack);
1061 Pack.New[0].wasDeducedFromArrayBound());
1067 if (Pack.Outer->DeferredDeduction.isNull()) {
1070 Pack.Outer->DeferredDeduction = NewPack;
1073 Loc = &Pack.Outer->DeferredDeduction;
1075 Loc = &Deduced[Pack.Index];
1081 S.
Context, OldPack, NewPack, DeducePackIfNotAlreadyDeduced);
1083 Info.AggregateDeductionCandidateHasMismatchedArity =
1089 if (!Result.isNull() && !Pack.DeferredDeduction.isNull()) {
1091 NewPack = Pack.DeferredDeduction;
1095 NamedDecl *Param = TemplateParams->getParam(Pack.Index);
1096 if (Result.isNull()) {
1098 Info.FirstArg = OldPack;
1099 Info.SecondArg = NewPack;
1100 return TemplateDeductionResult::Inconsistent;
1106 if (*Expansions != PackElements) {
1108 Info.FirstArg = Result;
1109 return TemplateDeductionResult::IncompletePack;
1116 return TemplateDeductionResult::Success;
1124 unsigned PackElements = 0;
1125 bool IsPartiallyExpanded =
false;
1126 bool DeducePackIfNotAlreadyDeduced =
false;
1127 bool DeducedFromEarlierParameter =
false;
1128 bool FinishingDeduction =
false;
1130 std::optional<unsigned> FixedNumExpansions;
1142 bool FinishingDeduction,
T &&DeductFunc) {
1152 = dyn_cast<PackExpansionType>(Params[
ParamIdx]);
1157 if (ArgIdx >= Args.size())
1158 return TemplateDeductionResult::MiscellaneousDeductionFailure;
1160 if (isa<PackExpansionType>(Args[ArgIdx])) {
1165 return TemplateDeductionResult::MiscellaneousDeductionFailure;
1169 DeductFunc(S, TemplateParams,
ParamIdx, ArgIdx,
1170 Params[
ParamIdx].getUnqualifiedType(),
1171 Args[ArgIdx].getUnqualifiedType(), Info, Deduced, POK);
1172 Result != TemplateDeductionResult::Success)
1187 PackDeductionScope PackScope(S, TemplateParams, Deduced, Info, Pattern,
1189 FinishingDeduction);
1193 if (
ParamIdx + 1 == Params.size() || PackScope.hasFixedArity()) {
1194 for (; ArgIdx < Args.size() && PackScope.hasNextElement(); ++ArgIdx) {
1197 S, TemplateParams,
ParamIdx, ArgIdx,
1199 Info, Deduced, POK);
1200 Result != TemplateDeductionResult::Success)
1202 PackScope.nextPackElement();
1223 if (NumExpansions && !PackScope.isPartiallyExpanded()) {
1224 for (
unsigned I = 0; I != *NumExpansions && ArgIdx < Args.size();
1226 PackScope.nextPackElement();
1232 if (
auto Result = PackScope.finish();
1233 Result != TemplateDeductionResult::Success)
1244 isa<PackExpansionType>(Args[ArgIdx]))
1245 return TemplateDeductionResult::Success;
1248 if (ArgIdx < Args.size())
1249 return TemplateDeductionResult::MiscellaneousDeductionFailure;
1251 return TemplateDeductionResult::Success;
1291 llvm::SmallBitVector *HasDeducedParam) {
1292 return ::DeduceForEachType(
1293 S, TemplateParams, Params, Args, Info, Deduced, POK,
1299 bool HasDeducedAnyParamCopy =
false;
1301 S, TemplateParams,
P, A, Info, Deduced, TDF, POK,
1302 false, &HasDeducedAnyParamCopy);
1303 if (HasDeducedAnyParam && HasDeducedAnyParamCopy)
1304 *HasDeducedAnyParam =
true;
1305 if (HasDeducedParam && HasDeducedAnyParamCopy)
1306 (*HasDeducedParam)[
ParamIdx] =
true;
1320 if (ParamQs == ArgQs)
1364 if (!Guide || !Guide->isImplicit())
1366 return Guide->getDeducedTemplate()->getTemplateParameters()->size();
1376 if (ParamRef->getPointeeType().getQualifiers())
1379 return TypeParm && TypeParm->
getIndex() >= FirstInnerIndex;
1407 bool *HasDeducedAnyParam) {
1433 bool HasDeducedAnyParam;
1435 llvm::MapVector<const CXXRecordDecl *, MatchValue> Matches;
1440 assert(
T->
isRecordType() &&
"Base class that isn't a record?");
1442 ToVisit.push_back(
T);
1451 while (!ToVisit.empty()) {
1452 QualType NextT = ToVisit.pop_back_val();
1457 bool HasDeducedAnyParamCopy =
false;
1460 &HasDeducedAnyParamCopy);
1466 Matches.insert({RD, {DeducedCopy, HasDeducedAnyParamCopy}});
1477 if (Matches.size() > 1) {
1479 for (
const auto &Match : Matches)
1480 AddBases(Match.first);
1484 while (Matches.size() > 1 && !ToVisit.empty()) {
1485 const CXXRecordDecl *RD = ToVisit.pop_back_val()->getAsCXXRecordDecl();
1494 if (Matches.empty())
1496 if (Matches.size() > 1)
1499 std::swap(Matches.front().second.Deduced, Deduced);
1500 if (
bool HasDeducedAnyParamCopy = Matches.front().second.HasDeducedAnyParam;
1501 HasDeducedAnyParamCopy && HasDeducedAnyParam)
1502 *HasDeducedAnyParam = HasDeducedAnyParamCopy;
1511 return std::min(POK, PartialOrderingKind::NonCall);
1543 bool *HasDeducedAnyParam) {
1547 if (
const auto *AExp = dyn_cast<PackExpansionType>(A))
1548 A = AExp->getPattern();
1551 if (POK == PartialOrderingKind::Call) {
1629 TDF &= ~TDF_TopLevelParameterTypeList;
1632 P =
P->getPointeeType();
1649 unsigned Index = TTP->getIndex();
1664 Info.
Param = cast<TemplateTypeParmDecl>(TemplateParams->
getParam(Index));
1676 "saw template type parameter with wrong depth");
1678 "Unresolved overloaded function");
1698 Info.
Param = cast<TemplateTypeParmDecl>(TemplateParams->
getParam(Index));
1718 Info.
Param = cast<TemplateTypeParmDecl>(TemplateParams->
getParam(Index));
1725 if (HasDeducedAnyParam)
1726 *HasDeducedAnyParam =
true;
1766 if (!
P->isDependentType()) {
1782 switch (
P.getCanonicalType()->getTypeClass()) {
1784#define NON_CANONICAL_TYPE(Class, Base) \
1785 case Type::Class: llvm_unreachable("deducing non-canonical type: " #Class);
1786#define TYPE(Class, Base)
1787#include "clang/AST/TypeNodes.inc"
1789 case Type::TemplateTypeParm:
1790 case Type::SubstTemplateTypeParmPack:
1791 llvm_unreachable(
"Type nodes handled above");
1799 if (
P->isDependentType())
1803 case Type::VariableArray:
1805 case Type::FunctionNoProto:
1808 case Type::ObjCObject:
1809 case Type::ObjCInterface:
1810 case Type::ObjCObjectPointer:
1820 case Type::Complex: {
1825 S, TemplateParams, CP->getElementType(), CA->getElementType(), Info,
1827 false, HasDeducedAnyParam);
1831 case Type::Atomic: {
1836 S, TemplateParams, PA->getValueType(), AA->getValueType(), Info,
1838 false, HasDeducedAnyParam);
1842 case Type::Pointer: {
1853 PointeeType, Info, Deduced,
1856 false, HasDeducedAnyParam);
1860 case Type::LValueReference: {
1867 S, TemplateParams, RP->getPointeeType(), RA->getPointeeType(), Info,
1869 false, HasDeducedAnyParam);
1873 case Type::RValueReference: {
1880 S, TemplateParams, RP->getPointeeType(), RA->getPointeeType(), Info,
1882 false, HasDeducedAnyParam);
1886 case Type::IncompleteArray: {
1892 assert(IAP &&
"Template parameter not of incomplete array type");
1895 S, TemplateParams, IAP->getElementType(), IAA->getElementType(), Info,
1898 false, HasDeducedAnyParam);
1902 case Type::ConstantArray: {
1906 if (!CAA || CAA->getSize() != CAP->getSize())
1910 S, TemplateParams, CAP->getElementType(), CAA->getElementType(), Info,
1913 false, HasDeducedAnyParam);
1917 case Type::DependentSizedArray: {
1926 S, TemplateParams, DAP->getElementType(), AA->getElementType(),
1929 false, HasDeducedAnyParam);
1942 "saw non-type template parameter with wrong depth");
1943 if (
const auto *CAA = dyn_cast<ConstantArrayType>(AA)) {
1944 llvm::APSInt Size(CAA->getSize());
1947 true, Info, POK != PartialOrderingKind::None,
1948 Deduced, HasDeducedAnyParam);
1950 if (
const auto *DAA = dyn_cast<DependentSizedArrayType>(AA))
1951 if (DAA->getSizeExpr())
1953 S, TemplateParams, NTTP, DAA->getSizeExpr(), Info,
1954 POK != PartialOrderingKind::None, Deduced, HasDeducedAnyParam);
1963 case Type::FunctionProto: {
1969 if (FPP->getMethodQuals() != FPA->getMethodQuals() ||
1970 FPP->getRefQualifier() != FPA->getRefQualifier() ||
1971 FPP->isVariadic() != FPA->isVariadic())
1976 S, TemplateParams, FPP->getReturnType(), FPA->getReturnType(),
1978 false, HasDeducedAnyParam);
1984 S, TemplateParams, FPP->param_types(), FPA->param_types(), Info,
1997 Expr *NoexceptExpr = FPP->getNoexceptExpr();
2002 "saw non-type template parameter with wrong depth");
2004 llvm::APSInt Noexcept(1);
2005 switch (FPA->canThrow()) {
2016 POK != PartialOrderingKind::None, Deduced, HasDeducedAnyParam);
2019 if (
Expr *ArgNoexceptExpr = FPA->getNoexceptExpr())
2021 S, TemplateParams, NTTP, ArgNoexceptExpr, Info,
2022 POK != PartialOrderingKind::None, Deduced, HasDeducedAnyParam);
2035 case Type::InjectedClassName:
2044 case Type::TemplateSpecialization: {
2049 POK != PartialOrderingKind::None,
2050 Deduced, HasDeducedAnyParam);
2056 S, TemplateParams,
P, A, Info, POK != PartialOrderingKind::None,
2057 Deduced, HasDeducedAnyParam);
2072 Deduced = DeducedOrig;
2076 POK != PartialOrderingKind::None,
2077 Deduced, HasDeducedAnyParam);
2091 case Type::MemberPointer: {
2108 S, TemplateParams, PPT, APT, Info, Deduced, SubTDF,
2110 false, HasDeducedAnyParam);
2114 S, TemplateParams,
QualType(MPP->getClass(), 0),
2115 QualType(MPA->getClass(), 0), Info, Deduced, SubTDF,
2117 false, HasDeducedAnyParam);
2125 case Type::BlockPointer: {
2131 S, TemplateParams, BPP->getPointeeType(), BPA->getPointeeType(), Info,
2133 false, HasDeducedAnyParam);
2139 case Type::ExtVector: {
2144 if (VP->getNumElements() != VA->getNumElements())
2146 ElementType = VA->getElementType();
2151 ElementType = VA->getElementType();
2157 S, TemplateParams, VP->getElementType(), ElementType, Info, Deduced,
2159 false, HasDeducedAnyParam);
2162 case Type::DependentVector: {
2168 S, TemplateParams, VP->getElementType(), VA->getElementType(),
2170 false, HasDeducedAnyParam);
2181 ArgSize = VA->getNumElements();
2187 Info, POK != PartialOrderingKind::None, Deduced,
2188 HasDeducedAnyParam);
2194 S, TemplateParams, VP->getElementType(), VA->getElementType(),
2196 false, HasDeducedAnyParam);
2207 S, TemplateParams, NTTP, VA->getSizeExpr(), Info,
2208 POK != PartialOrderingKind::None, Deduced, HasDeducedAnyParam);
2217 case Type::DependentSizedExtVector: {
2223 S, TemplateParams, VP->getElementType(), VA->getElementType(),
2225 false, HasDeducedAnyParam);
2236 ArgSize = VA->getNumElements();
2241 S, TemplateParams, NTTP, ArgSize, S.
Context.
IntTy,
true, Info,
2242 POK != PartialOrderingKind::None, Deduced, HasDeducedAnyParam);
2248 S, TemplateParams, VP->getElementType(), VA->getElementType(),
2250 false, HasDeducedAnyParam);
2261 S, TemplateParams, NTTP, VA->getSizeExpr(), Info,
2262 POK != PartialOrderingKind::None, Deduced, HasDeducedAnyParam);
2272 case Type::ConstantMatrix: {
2279 if (MP->getNumRows() != MA->getNumRows() ||
2280 MP->getNumColumns() != MA->getNumColumns()) {
2285 S, TemplateParams, MP->getElementType(), MA->getElementType(), Info,
2287 false, HasDeducedAnyParam);
2290 case Type::DependentSizedMatrix: {
2300 false, HasDeducedAnyParam);
2305 auto DeduceMatrixArg =
2306 [&S, &Info, &Deduced, &TemplateParams, &HasDeducedAnyParam, POK](
2310 const auto *ACM = dyn_cast<ConstantMatrixType>(A);
2311 const auto *ADM = dyn_cast<DependentSizedMatrixType>(A);
2312 if (!ParamExpr->isValueDependent()) {
2313 std::optional<llvm::APSInt> ParamConst =
2314 ParamExpr->getIntegerConstantExpr(S.
Context);
2319 if ((ACM->*GetArgDimension)() == *ParamConst)
2324 Expr *ArgExpr = (ADM->*GetArgDimensionExpr)();
2325 if (std::optional<llvm::APSInt> ArgConst =
2327 if (*ArgConst == *ParamConst)
2338 llvm::APSInt ArgConst(
2340 ArgConst = (ACM->*GetArgDimension)();
2343 true, Info, POK != PartialOrderingKind::None,
2344 Deduced, HasDeducedAnyParam);
2348 S, TemplateParams, NTTP, (ADM->*GetArgDimensionExpr)(), Info,
2349 POK != PartialOrderingKind::None, Deduced, HasDeducedAnyParam);
2352 if (
auto Result = DeduceMatrixArg(MP->getRowExpr(), MA,
2358 return DeduceMatrixArg(MP->getColumnExpr(), MA,
2366 case Type::DependentAddressSpace: {
2372 S, TemplateParams, ASP->getPointeeType(), ASA->getPointeeType(),
2374 false, HasDeducedAnyParam);
2385 S, TemplateParams, NTTP, ASA->getAddrSpaceExpr(), Info,
2386 POK != PartialOrderingKind::None, Deduced, HasDeducedAnyParam);
2396 S, TemplateParams, ASP->getPointeeType(),
2399 false, HasDeducedAnyParam);
2410 S, TemplateParams, NTTP, ArgAddressSpace, S.
Context.
IntTy,
true,
2411 Info, POK != PartialOrderingKind::None, Deduced,
2412 HasDeducedAnyParam);
2417 case Type::DependentBitInt: {
2421 if (IP->isUnsigned() != IA->isUnsigned())
2430 ArgSize = IA->getNumBits();
2433 S, TemplateParams, NTTP, ArgSize, S.
Context.
IntTy,
true, Info,
2434 POK != PartialOrderingKind::None, Deduced, HasDeducedAnyParam);
2438 if (IP->isUnsigned() != IA->isUnsigned())
2446 case Type::TypeOfExpr:
2448 case Type::DependentName:
2449 case Type::UnresolvedUsing:
2450 case Type::Decltype:
2451 case Type::UnaryTransform:
2452 case Type::DeducedTemplateSpecialization:
2453 case Type::DependentTemplateSpecialization:
2454 case Type::PackExpansion:
2456 case Type::ArrayParameter:
2457 case Type::HLSLAttributedResource:
2461 case Type::PackIndexing: {
2467 false, HasDeducedAnyParam);
2473 llvm_unreachable(
"Invalid Type Class!");
2481 bool *HasDeducedAnyParam) {
2488 switch (
P.getKind()) {
2490 llvm_unreachable(
"Null template argument in parameter list");
2495 S, TemplateParams,
P.getAsType(), A.
getAsType(), Info, Deduced, 0,
2497 : PartialOrderingKind::None,
2498 false, HasDeducedAnyParam);
2510 HasDeducedAnyParam);
2516 llvm_unreachable(
"caller should handle pack expansions");
2564 HasDeducedAnyParam);
2569 Deduced, HasDeducedAnyParam);
2585 llvm_unreachable(
"Unknown template argument kind");
2591 llvm_unreachable(
"Argument packs should be expanded by the caller!");
2594 llvm_unreachable(
"Invalid TemplateArgument Kind!");
2607 if (ArgIdx == Args.size())
2614 assert(ArgIdx == Args.size() - 1 &&
"Pack not at the end of argument list?");
2617 return ArgIdx < Args.size();
2623 bool FoundPackExpansion =
false;
2624 for (
const auto &A : Args) {
2625 if (FoundPackExpansion)
2633 if (A.isPackExpansion())
2634 FoundPackExpansion =
true;
2648 if (
PackFold == PackFold::ArgumentToParameter)
2664 if (!
P.isPackExpansion()) {
2669 return NumberOfArgumentsMustMatch
2676 if (As[ArgIdx].isPackExpansion())
2681 if (
PackFold == PackFold::ArgumentToParameter)
2685 HasDeducedAnyParam);
2704 PackDeductionScope PackScope(S, TemplateParams, Deduced, Info, Pattern);
2710 PackScope.hasNextElement();
2713 if (
PackFold == PackFold::ArgumentToParameter)
2718 HasDeducedAnyParam);
2722 PackScope.nextPackElement();
2727 if (
auto Result = PackScope.finish();
2739 bool NumberOfArgumentsMustMatch) {
2740 return ::DeduceTemplateArguments(
2741 *
this, TemplateParams, Ps, As, Info, Deduced, NumberOfArgumentsMustMatch,
2742 false, PackFold::ParameterToArgument,
2751 bool PackExpansionMatchesPack =
false) {
2754 if (PackExpansionMatchesPack &&
X.isPackExpansion() && !Y.
isPackExpansion())
2755 X =
X.getPackExpansionPattern();
2760 switch (
X.getKind()) {
2762 llvm_unreachable(
"Comparing NULL template argument");
2785 return X.structurallyEquals(Y);
2788 llvm::FoldingSetNodeID XID, YID;
2789 X.getAsExpr()->Profile(XID, Context,
true);
2795 unsigned PackIterationSize =
X.pack_size();
2804 bool XHasMoreArg =
X.pack_size() > Y.
pack_size();
2805 if (!(XHasMoreArg &&
X.pack_elements().back().isPackExpansion()) &&
2806 !(!XHasMoreArg && Y.
pack_elements().back().isPackExpansion()))
2815 for (
unsigned i = 0; i < PackIterationSize; ++i)
2817 PackExpansionMatchesPack))
2823 llvm_unreachable(
"Invalid TemplateArgument Kind!");
2832 llvm_unreachable(
"Can't get a NULL template argument here");
2867 Builder.MakeTrivial(
Context, DTN->getQualifier(),
Loc);
2870 Builder.MakeTrivial(
Context, QTN->getQualifier(),
Loc);
2887 llvm_unreachable(
"Invalid TemplateArgument Kind!");
2905 unsigned ArgumentPackIndex) {
2927 CanonicalPackedArgsBuilder;
2935 "deduced nested pack");
2942 diag::err_template_arg_deduced_incomplete_pack)
2946 if (ConvertArg(InnerArg, SugaredPackedArgsBuilder.size()))
2950 SugaredPackedArgsBuilder.push_back(SugaredOutput.pop_back_val());
2951 CanonicalPackedArgsBuilder.push_back(CanonicalOutput.pop_back_val());
2956 if (SugaredPackedArgsBuilder.empty()) {
2961 if (
auto *NTTP = dyn_cast<NonTypeTemplateParmDecl>(Param)) {
2963 NTTP, SugaredOutput,
2966 S.
SubstType(NTTP->getType(), Args, NTTP->getLocation(),
2967 NTTP->getDeclName()).isNull())
2969 }
else if (
auto *TTP = dyn_cast<TemplateTemplateParmDecl>(Param)) {
2980 SugaredOutput.push_back(
2983 S.
Context, CanonicalPackedArgsBuilder));
2987 return ConvertArg(Arg, 0);
2997template <
typename TemplateDeclT>
2999 Sema &S, TemplateDeclT *Template,
bool IsDeduced,
3005 unsigned NumAlreadyConverted = 0,
bool *IsIncomplete =
nullptr) {
3008 for (
unsigned I = 0, N = TemplateParams->
size(); I != N; ++I) {
3017 PackDeductionScope(S, TemplateParams, Deduced, Info, I).finish();
3022 if (!Deduced[I].isNull()) {
3023 if (I < NumAlreadyConverted) {
3028 CurrentInstantiationScope->getPartiallySubstitutedPack() == Param) {
3031 CurrentInstantiationScope->ResetPartiallySubstitutedPack();
3038 SugaredBuilder.push_back(Deduced[I]);
3039 CanonicalBuilder.push_back(
3048 IsDeduced, SugaredBuilder,
3049 CanonicalBuilder)) {
3067 *IsIncomplete =
true;
3068 SugaredBuilder.push_back({});
3069 CanonicalBuilder.push_back({});
3074 bool HasDefaultArg =
false;
3077 assert(isa<ClassTemplatePartialSpecializationDecl>(Template) ||
3078 isa<VarTemplatePartialSpecializationDecl>(Template));
3087 if (Rec->isLambda())
3088 if (
auto *Method = dyn_cast<CXXMethodDecl>(Rec->getDeclContext())) {
3090 ThisTypeQuals = Method->getMethodQualifiers();
3098 SugaredBuilder, CanonicalBuilder, HasDefaultArg);
3131 if (
auto *DC = dyn_cast<DeclContext>(
D))
3137 static constexpr bool value =
false;
3141 static constexpr bool value =
true;
3145 static constexpr bool value =
true;
3147template <
typename TemplateDeclT>
3162template <
typename TemplateDeclT>
3169 Template->getAssociatedConstraints(AssociatedConstraints);
3171 std::optional<ArrayRef<TemplateArgument>> Innermost;
3175 Innermost = CanonicalDeducedArgs;
3178 Template, Template->getDeclContext(),
false, Innermost,
3202template <
typename T>
3203static std::enable_if_t<IsPartialSpecialization<T>::value,
3206 Sema &S,
T *Partial,
bool IsPartialOrdering,
3222 S, Partial, IsPartialOrdering, Deduced, Info, SugaredBuilder,
3233 Info.
reset(SugaredDeducedArgumentList, CanonicalDeducedArgumentList);
3241 auto *Template = Partial->getSpecializedTemplate();
3243 Partial->getTemplateArgsAsWritten();
3254 if (
ParamIdx >= Partial->getTemplateParameters()->size())
3255 ParamIdx = Partial->getTemplateParameters()->size() - 1;
3258 Partial->getTemplateParameters()->getParam(
ParamIdx));
3260 Info.
FirstArg = (*PartialTemplArgInfo)[ArgIdx].getArgument();
3266 CanonicalConvertedInstArgs;
3268 Template, Partial->getLocation(), InstArgs, {},
false,
3269 SugaredConvertedInstArgs, CanonicalConvertedInstArgs,
3276 for (
unsigned I = 0,
E = TemplateParams->
size(); I !=
E; ++I) {
3279 IsPartialOrdering)) {
3290 if (!IsPartialOrdering) {
3292 S, Partial, SugaredBuilder, CanonicalBuilder, Info);
3321 SugaredBuilder, CanonicalBuilder,
3329 for (
unsigned I = 0,
E = TemplateParams->
size(); I !=
E; ++I) {
3345 S, Template, SugaredBuilder, CanonicalBuilder, Info);
3372 S, TD,
false, Deduced, Info, SugaredBuilder,
3381 CanonicalBuilder, Info);
3391template <
typename T>
3392static std::enable_if_t<IsPartialSpecialization<T>::value,
3397 if (Partial->isInvalidDecl())
3416 Deduced.resize(Partial->getTemplateParameters()->size());
3418 S, Partial->getTemplateParameters(),
3419 Partial->getTemplateArgs().asArray(), TemplateArgs, Info, Deduced,
3421 PackFold::ParameterToArgument,
3437 Result = ::FinishTemplateArgumentDeduction(S, Partial,
3439 TemplateArgs, Deduced, Info);
3448 return ::DeduceTemplateArguments(*
this, Partial, TemplateArgs, Info);
3454 return ::DeduceTemplateArguments(*
this, Partial, TemplateArgs, Info);
3464 if (
const auto *CTD = dyn_cast<ClassTemplateDecl>(TD)) {
3467 }
else if (
const auto *
AliasTemplate = dyn_cast<TypeAliasTemplateDecl>(TD)) {
3468 PType =
AliasTemplate->getTemplatedDecl()->getUnderlyingType();
3470 assert(
false &&
"Expected a class or alias template");
3489 return DeducedResult;
3502 Result = ::FinishTemplateArgumentDeduction(*this, TD, Deduced, Info);
3511 return Spec->getTemplateName().getAsTemplateDecl() !=
nullptr;
3537 if (ExplicitTemplateArgs.
size() == 0) {
3541 ParamTypes.push_back(
P->getType());
3571 ExplicitTemplateArgs, {},
true,
3572 SugaredBuilder, CanonicalBuilder,
3575 unsigned Index = SugaredBuilder.size();
3576 if (Index >= TemplateParams->
size())
3589 CanonicalExplicitArgumentList);
3601 unsigned PartiallySubstitutedPackIndex = -1u;
3602 if (!SugaredBuilder.empty()) {
3605 auto *Param = TemplateParams->
getParam(SugaredBuilder.size() - 1);
3609 if (!Expansions || Arg.
pack_size() < *Expansions) {
3610 PartiallySubstitutedPackIndex = SugaredBuilder.size() - 1;
3619 assert(Proto &&
"Function template does not have a prototype?");
3627 SugaredExplicitArgumentList->
asArray(),
3637 nullptr, ExtParamInfos))
3654 ThisTypeQuals = Method->getMethodQualifiers();
3668 Diag(
Function->getLocation(), diag::err_kern_type_not_void_return)
3679 nullptr, ExtParamInfos))
3703 Deduced.reserve(TemplateParams->
size());
3704 for (
unsigned I = 0, N = SugaredExplicitArgumentList->
size(); I != N; ++I) {
3706 if (I == PartiallySubstitutedPackIndex)
3709 Deduced.push_back(Arg);
3778 if (AQuals == DeducedAQuals) {
3796 bool ObjCLifetimeConversion =
false;
3800 ObjCLifetimeConversion) ||
3846 if (PD->isParameterPack()) {
3847 unsigned NumExpansions =
3849 if (Idx + NumExpansions >
ParamIdx)
3851 Idx += NumExpansions;
3859 llvm_unreachable(
"parameter index would not be produced from template");
3871 return isa<CXXConstructorDecl>(
D)
3872 ? cast<CXXConstructorDecl>(
D)->getExplicitSpecifier()
3873 : cast<CXXConversionDecl>(
D)->getExplicitSpecifier();
3876 isa<CXXConstructorDecl>(
D)
3877 ? cast<CXXConstructorDecl>(
D)->setExplicitSpecifier(ES)
3878 : cast<CXXConversionDecl>(
D)->setExplicitSpecifier(ES);
3889 S, Info.
getLocation(), FunctionTemplate, DeducedArgs,
3910 bool PartialOverloading, llvm::function_ref<
bool()> CheckNonDependent) {
3930 bool IsIncomplete =
false;
3935 NumExplicitlySpecified, PartialOverloading ? &IsIncomplete :
nullptr);
3944 Info.
reset(SugaredDeducedArgumentList, CanonicalDeducedArgumentList);
3977 if (!IsLambda && !IsIncomplete) {
3998 if (CheckNonDependent())
4015 CanonicalDeducedArgumentList &&
4035 if (IsLambda && !IsIncomplete) {
4051 if (isa<CXXConstructorDecl, CXXConversionDecl>(
Specialization)) {
4060 if (OriginalCallArgs) {
4065 llvm::SmallDenseMap<std::pair<unsigned, QualType>,
QualType> DeducedATypes;
4066 for (
unsigned I = 0, N = OriginalCallArgs->size(); I != N; ++I) {
4070 unsigned ExplicitOffset =
4090 if (CacheEntry.
isNull()) {
4099 DeducedA = CacheEntry;
4114 auto [Pos, Inserted] =
4128 if (S.
getLangOpts().CPlusPlus14 && Fn->getReturnType()->isUndeducedType() &&
4133 if (Method->isImplicitObjectMemberFunction()) {
4154 bool ParamWasReference,
4163 if (ParamWasReference)
4180 nullptr, FailedTSC))
4221 if (ArgType.
isNull())
continue;
4241 Deduced(TemplateParams->
size());
4244 S, TemplateParams, ParamType, ArgType, Info, Deduced, TDF,
4245 PartialOrderingKind::None,
false,
4284 assert(Arg &&
"expected a non-null arg expression");
4286 ParamRefType !=
nullptr, FailedTSC);
4294 assert(Arg &&
"expected a non-null arg expression");
4349 (isa<PointerType>(ParamType) &&
4368 bool DecomposedParam,
unsigned ArgIdx,
unsigned TDF,
4393 ElTy = ArrTy->getElementType();
4403 if (isa<DesignatedInitExpr>(
E))
4410 S, TemplateParams, 0, ElTy,
E->
getType(),
4412 OriginalCallArgs,
true, ArgIdx, TDF);
4420 if (
auto *DependentArrTy = dyn_cast_or_null<DependentSizedArrayType>(ArrTy)) {
4431 S, TemplateParams, NTTP, llvm::APSInt(Size),
T,
4432 true, Info,
false, Deduced,
4451 bool DecomposedParam,
unsigned ArgIdx,
unsigned TDF,
4454 QualType OrigParamType = ParamType;
4459 S, TemplateParams, FirstInnerIndex, ParamType, ArgType,
4460 ArgClassification, Arg, TDF, FailedTSC))
4464 if (
InitListExpr *ILE = dyn_cast_if_present<InitListExpr>(Arg))
4466 Deduced, OriginalCallArgs, ArgIdx, TDF);
4474 OriginalCallArgs.push_back(
4477 S, TemplateParams, ParamType, ArgType, Info, Deduced, TDF,
4478 PartialOrderingKind::None,
false,
4486 bool PartialOverloading,
bool AggregateDeductionCandidate,
4493 unsigned NumParams =
Function->getNumParams();
4494 bool HasExplicitObject =
false;
4495 int ExplicitObjectOffset = 0;
4496 if (
Function->hasCXXExplicitFunctionObjectParameter()) {
4497 HasExplicitObject =
true;
4498 ExplicitObjectOffset = 1;
4507 if (Args.size() <
Function->getMinRequiredExplicitArguments() &&
4508 !PartialOverloading)
4511 PartialOverloading)) {
4513 if (Proto->isTemplateVariadic())
4515 else if (!Proto->isVariadic())
4526 unsigned NumExplicitlySpecified = 0;
4527 if (ExplicitTemplateArgs) {
4530 Result = SubstituteExplicitTemplateArguments(
4531 FunctionTemplate, *ExplicitTemplateArgs, Deduced, ParamTypes, nullptr,
4537 NumExplicitlySpecified = Deduced.size();
4540 for (
unsigned I = 0; I != NumParams; ++I)
4541 ParamTypes.push_back(
Function->getParamDecl(I)->getType());
4547 auto DeduceCallArgument = [&](
QualType ParamType,
unsigned ArgIdx,
4548 bool ExplicitObjectArgument) {
4556 if (ExplicitObjectArgument) {
4559 *
this, TemplateParams, FirstInnerIndex, ParamType, ObjectType,
4560 ObjectClassification,
4561 nullptr, Info, Deduced, OriginalCallArgs,
4567 *
this, TemplateParams, FirstInnerIndex, ParamType,
4568 Args[ArgIdx]->getType(), Args[ArgIdx]->Classify(
getASTContext()),
4569 Args[ArgIdx], Info, Deduced, OriginalCallArgs,
false,
4574 Deduced.resize(TemplateParams->
size());
4576 for (
unsigned ParamIdx = 0, NumParamTypes = ParamTypes.size(), ArgIdx = 0;
4581 dyn_cast<PackExpansionType>(ParamType);
4582 if (!ParamExpansion) {
4584 if (ArgIdx >= Args.size() && !(HasExplicitObject &&
ParamIdx == 0))
4587 ParamTypesForArgChecking.push_back(ParamType);
4589 if (
ParamIdx == 0 && HasExplicitObject) {
4593 if (
auto Result = DeduceCallArgument(ParamType, 0,
4600 if (
auto Result = DeduceCallArgument(ParamType, ArgIdx++,
4608 bool IsTrailingPack =
ParamIdx + 1 == NumParamTypes;
4611 PackDeductionScope PackScope(*
this, TemplateParams, Deduced, Info,
4613 AggregateDeductionCandidate && IsTrailingPack);
4631 if (IsTrailingPack || PackScope.hasFixedArity()) {
4632 for (; ArgIdx < Args.size() && PackScope.hasNextElement();
4633 PackScope.nextPackElement(), ++ArgIdx) {
4634 ParamTypesForArgChecking.push_back(ParamPattern);
4635 if (
auto Result = DeduceCallArgument(ParamPattern, ArgIdx,
4644 std::optional<unsigned> NumExpansions =
4646 if (NumExpansions && !PackScope.isPartiallyExpanded()) {
4647 for (
unsigned I = 0; I != *NumExpansions && ArgIdx < Args.size();
4649 ParamTypesForArgChecking.push_back(ParamPattern);
4652 PackScope.nextPackElement();
4654 }
else if (!IsTrailingPack && !PackScope.isPartiallyExpanded() &&
4655 PackScope.isDeducedFromEarlierParameter()) {
4668 std::optional<unsigned> ArgPosAfterSubstitution =
4669 PackScope.getSavedPackSizeIfAllEqual();
4670 if (!ArgPosAfterSubstitution)
4673 unsigned PackArgEnd = ArgIdx + *ArgPosAfterSubstitution;
4674 for (; ArgIdx < PackArgEnd && ArgIdx < Args.size(); ArgIdx++) {
4675 ParamTypesForArgChecking.push_back(ParamPattern);
4677 DeduceCallArgument(ParamPattern, ArgIdx,
4682 PackScope.nextPackElement();
4689 if (
auto Result = PackScope.finish();
4700 Result = FinishTemplateArgumentDeduction(
4701 FunctionTemplate, Deduced, NumExplicitlySpecified, Specialization, Info,
4702 &OriginalCallArgs, PartialOverloading, [&, CallingCtx]() {
4703 ContextRAII SavedContext(*this, CallingCtx);
4704 return CheckNonDependent(ParamTypesForArgChecking);
4712 bool AdjustExceptionSpec) {
4713 if (ArgFunctionType.
isNull())
4714 return ArgFunctionType;
4719 bool Rebuild =
false;
4722 if (EPI.ExtInfo.getCC() != CC) {
4723 EPI.
ExtInfo = EPI.ExtInfo.withCallingConv(CC);
4727 bool NoReturn = FunctionTypeP->getNoReturnAttr();
4728 if (EPI.ExtInfo.getNoReturn() != NoReturn) {
4729 EPI.ExtInfo = EPI.ExtInfo.withNoReturn(NoReturn);
4733 if (AdjustExceptionSpec && (FunctionTypeP->hasExceptionSpec() ||
4735 EPI.ExceptionSpec = FunctionTypeP->getExtProtoInfo().ExceptionSpec;
4740 return ArgFunctionType;
4750 bool IsAddressOfFunction) {
4762 unsigned NumExplicitlySpecified = 0;
4764 if (ExplicitTemplateArgs) {
4767 Result = SubstituteExplicitTemplateArguments(
4768 FunctionTemplate, *ExplicitTemplateArgs, Deduced, ParamTypes,
4769 &FunctionType, Info);
4774 NumExplicitlySpecified = Deduced.size();
4780 if (!IsAddressOfFunction)
4789 Deduced.resize(TemplateParams->
size());
4793 bool HasDeducedReturnType =
false;
4795 Function->getReturnType()->getContainedAutoType()) {
4797 HasDeducedReturnType =
true;
4805 *
this, TemplateParams,
FunctionType, ArgFunctionType, Info, Deduced,
4806 TDF, PartialOrderingKind::None,
false,
4814 Result = FinishTemplateArgumentDeduction(FunctionTemplate, Deduced,
4815 NumExplicitlySpecified,
4816 Specialization, Info);
4823 if (HasDeducedReturnType && IsAddressOfFunction &&
4844 if (!IsAddressOfFunction) {
4850 if (HasDeducedReturnType) {
4859 if (!ArgFunctionType.
isNull()) {
4861 SpecializationType, ArgFunctionType)
4863 SpecializationType, ArgFunctionType)) {
4884 bool IsReferenceP =
P->isReferenceType();
4891 P = PRef->getPointeeType();
4901 if (!IsReferenceP) {
4903 P =
P.getUnqualifiedType();
4910 assert(!A->
isReferenceType() &&
"Reference types were handled above");
4915 if (
P->isArrayType())
4920 else if (
P->isFunctionType())
4925 P =
P.getUnqualifiedType();
4947 Deduced.resize(TemplateParams->
size());
4976 ParamType, ObjectType, ObjectClassification,
4977 nullptr, Info, Deduced, OriginalCallArgs,
4984 *
this, TemplateParams,
P, A, Info, Deduced, TDF,
4985 PartialOrderingKind::None,
false,
4996 Result = FinishTemplateArgumentDeduction(ConversionTemplate, Deduced, 0,
4997 ConversionSpecialized, Info,
5000 Specialization = cast_or_null<CXXConversionDecl>(ConversionSpecialized);
5009 bool IsAddressOfFunction) {
5012 IsAddressOfFunction);
5016 struct DependentAuto {
bool IsPack; };
5020 class SubstituteDeducedTypeTransform :
5023 bool ReplacementIsPack;
5028 SubstituteDeducedTypeTransform(
Sema &SemaRef, DependentAuto DA)
5030 ReplacementIsPack(DA.IsPack), UseTypeSugar(
true) {}
5032 SubstituteDeducedTypeTransform(
Sema &SemaRef,
QualType Replacement,
5033 bool UseTypeSugar =
true)
5035 Replacement(Replacement), ReplacementIsPack(
false),
5036 UseTypeSugar(UseTypeSugar) {}
5039 assert(isa<TemplateTypeParmType>(Replacement) &&
5040 "unexpected unsugared replacement kind");
5058 return TransformDesugared(TLB, TL);
5060 QualType Result = SemaRef.Context.getAutoType(
5069 QualType TransformDeducedTemplateSpecializationType(
5072 return TransformDesugared(TLB, TL);
5074 QualType Result = SemaRef.Context.getDeducedTemplateSpecializationType(
5076 Replacement, Replacement.isNull());
5094 return inherited::TransformExceptionSpec(
Loc, ESI, Exceptions, Changed);
5102 return TransformType(TLB, TL);
5118 Deduced,
TypeLoc.getNameLoc())));
5119 for (
unsigned I = 0,
C =
TypeLoc.getNumArgs(); I !=
C; ++I)
5125 false, SugaredConverted, CanonicalConverted))
5141 S.
getASTContext(), Concept->getDeclContext(), Concept->getLocation(),
5142 CanonicalConverted));
5149 llvm::raw_string_ostream OS(Buf);
5150 OS <<
"'" << Concept->getName();
5151 if (
TypeLoc.hasExplicitTemplateArgs()) {
5154 Type.getTypeConstraintConcept()->getTemplateParameters());
5158 diag::err_placeholder_constraints_not_satisfied)
5169 bool IgnoreConstraints,
5172 if (
Init->containsErrors())
5185 DependentAuto DependentResult = {
5188 if (!DependentDeduction &&
5190 Init->containsUnexpandedParameterPack())) {
5191 Result = SubstituteDeducedTypeTransform(*
this, DependentResult).Apply(
Type);
5192 assert(!
Result.isNull() &&
"substituting DependentTy can't fail");
5197 auto *String = dyn_cast<StringLiteral>(
Init);
5199 Diag(
Type.getBeginLoc(), diag::ext_c23_auto_non_plain_identifier);
5201 Result = SubstituteDeducedTypeTransform(*
this, DependentResult).Apply(TL);
5202 assert(!
Result.isNull() &&
"substituting DependentTy can't fail");
5208 Diag(
Type.getBeginLoc(), diag::ext_c23_auto_non_plain_identifier);
5211 auto *InitList = dyn_cast<InitListExpr>(
Init);
5213 Diag(
Init->getBeginLoc(), diag::err_auto_init_list_from_c)
5225 if (
Init->isTypeDependent()) {
5227 SubstituteDeducedTypeTransform(*
this, DependentResult).Apply(
Type);
5228 assert(!
Result.isNull() &&
"substituting DependentTy can't fail");
5240 Diag(
Init->getBeginLoc(), diag::err_decltype_auto_initializer_list);
5253 nullptr,
false,
false,
false);
5267 for (
Expr *
Init : InitList->inits()) {
5270 if (isa<DesignatedInitExpr>(
Init))
5273 *
this, TemplateParamsSt.get(), 0, TemplArg,
Init->getType(),
5282 <<
Init->getSourceRange();
5285 return DeductionFailed(TDK);
5290 DeducedFromInitRange =
Init->getSourceRange();
5294 Diag(
Loc, diag::err_auto_bitfield);
5298 SubstituteDeducedTypeTransform(*
this, TemplArg).Apply(
Type);
5299 assert(!FuncParam.
isNull() &&
5300 "substituting template parameter for 'auto' failed");
5302 *
this, TemplateParamsSt.get(), 0, FuncParam,
Init->getType(),
5305 false, 0, 0, FailedTSC);
5307 return DeductionFailed(TDK);
5344 assert((
bool)InitList == OriginalArg.DecomposedParam &&
5345 "decomposed non-init-list in auto deduction?");
5350 return DeductionFailed(TDK);
5360 return SubstituteDeducedTypeTransform(*
this, TypeToReplaceAuto)
5361 .TransformType(TypeWithAuto);
5367 return SubstituteDeducedTypeTransform(*
this, TypeToReplaceAuto)
5368 .TransformType(TypeWithAuto);
5372 return SubstituteDeducedTypeTransform(*
this, DependentAuto{
false})
5373 .TransformType(TypeWithAuto);
5378 return SubstituteDeducedTypeTransform(*
this, DependentAuto{
false})
5379 .TransformType(TypeWithAuto);
5384 return SubstituteDeducedTypeTransform(*
this, TypeToReplaceAuto,
5386 .TransformType(TypeWithAuto);
5391 return SubstituteDeducedTypeTransform(*
this, TypeToReplaceAuto,
5393 .TransformType(TypeWithAuto);
5398 if (isa<InitListExpr>(
Init))
5401 ? diag::err_init_capture_deduction_failure_from_init_list
5402 : diag::err_auto_var_deduction_failure_from_init_list)
5406 VDecl->
isInitCapture() ? diag::err_init_capture_deduction_failure
5407 : diag::err_auto_var_deduction_failure)
5409 <<
Init->getSourceRange();
5441 "failed to deduce lambda return type");
5468 Diag(
Loc, diag::err_auto_fn_used_before_defined) << FD;
5472 return StillUndeduced;
5516 "expected a member function with no explicit object parameter");
5532 bool IsIncompleteSubstitution =
false;
5538 if (InstP.
isNull() && !IsIncompleteSubstitution)
5540 if (!CheckConsistency)
5542 if (IsIncompleteSubstitution)
5547 if (
auto *PA = dyn_cast<PackExpansionType>(A);
5548 PA && !isa<PackExpansionType>(InstP))
5549 A = PA->getPattern();
5571 bool IsIncomplete =
false;
5574 S, FTD,
true, Deduced, Info, SugaredBuilder,
5575 CanonicalBuilder,
nullptr,
5586 Info.
reset(SugaredDeducedArgumentList, CanonicalDeducedArgumentList);
5611 assert(Proto1 && Proto2 &&
"Function templates must have prototypes");
5627 Proto1->
isVariadic() == Proto2->isVariadic() &&
5628 "shouldn't partial order functions with different qualifiers in a "
5629 "context where the function type is used");
5631 assert(Args1.empty() && Args2.empty() &&
5632 "Only call context should have arguments");
5634 Args2 = Proto2->getParamTypes();
5641 bool HasDeducedAnyParamFromReturnType =
false;
5644 S, TemplateParams, Proto2->getReturnType(), Proto1->
getReturnType(),
5645 Info, Deduced,
TDF_None, PartialOrderingKind::Call,
5647 &HasDeducedAnyParamFromReturnType) !=
5652 llvm::SmallBitVector HasDeducedParam;
5654 HasDeducedParam.resize(Args2.size());
5656 TDF_None, PartialOrderingKind::Call,
5658 &HasDeducedParam) !=
5670 bool AtLeastAsSpecialized;
5672 AtLeastAsSpecialized =
5673 ::FinishTemplateArgumentDeduction(
5674 S, FT2, Deduced, Info,
5675 [&](Sema &S, FunctionTemplateDecl *FTD,
5676 ArrayRef<TemplateArgument> DeducedArgs) {
5681 if (TPOC != TPOC_Call) {
5682 if (auto TDR = ::CheckDeductionConsistency(
5683 S, FTD, -1, Proto2->getReturnType(),
5684 Proto1->getReturnType(), DeducedArgs,
5685 HasDeducedAnyParamFromReturnType);
5686 TDR != TemplateDeductionResult::Success)
5690 if (TPOC == TPOC_Conversion)
5691 return TemplateDeductionResult::Success;
5693 return ::DeduceForEachType(
5694 S, TemplateParams, Args2, Args1, Info, Deduced,
5695 PartialOrderingKind::Call, true,
5696 [&](Sema &S, TemplateParameterList *, int ParamIdx,
5697 int ArgIdx, QualType P, QualType A,
5698 TemplateDeductionInfo &Info,
5699 SmallVectorImpl<DeducedTemplateArgument> &Deduced,
5700 PartialOrderingKind) {
5702 ArgIdx -= Args1Offset;
5703 return ::CheckDeductionConsistency(
5704 S, FTD, ArgIdx, P, A, DeducedArgs,
5705 HasDeducedParam[ParamIdx]);
5709 if (!AtLeastAsSpecialized)
5718 unsigned ArgIdx = 0, NumArgs = Deduced.size();
5719 for (; ArgIdx != NumArgs; ++ArgIdx)
5720 if (Deduced[ArgIdx].isNull())
5723 if (ArgIdx == NumArgs) {
5730 llvm::SmallBitVector UsedParameters(TemplateParams->size());
5733 for (
unsigned I = 0, N = Args2.size(); I != N; ++I)
5735 TemplateParams->getDepth(), UsedParameters);
5741 TemplateParams->getDepth(), UsedParameters);
5767 false, TemplateParams->getDepth(), UsedParameters);
5771 for (; ArgIdx != NumArgs; ++ArgIdx)
5774 if (Deduced[ArgIdx].isNull() && UsedParameters[ArgIdx])
5788 bool ShouldConvert1 =
false;
5789 bool ShouldConvert2 =
false;
5790 bool Args1Offset =
false;
5791 bool Args2Offset =
false;
5802 const CXXMethodDecl *Method1 = dyn_cast<CXXMethodDecl>(FD1);
5803 const CXXMethodDecl *Method2 = dyn_cast<CXXMethodDecl>(FD2);
5814 bool NonStaticMethod1 = Method1 && !Method1->isStatic(),
5815 NonStaticMethod2 = Method2 && !Method2->
isStatic();
5818 Params2Begin = Proto2->param_type_begin();
5820 size_t NumComparedArguments = NumCallArguments1;
5823 (NonStaticMethod1 && NonStaticMethod2) ||
5824 (OO !=
OO_None && OO != OO_Call && OO != OO_Subscript)) {
5826 NonStaticMethod1 && !Method1->hasCXXExplicitFunctionObjectParameter();
5829 NumComparedArguments += 1;
5831 if (ShouldConvert1) {
5835 : Proto2->param_type_begin()[0]->isRValueReferenceType();
5838 RawObj1Ty, IsRValRef2);
5839 Args1.push_back(Obj1Ty);
5842 if (ShouldConvert2) {
5845 ? Method1->getRefQualifier() ==
RQ_RValue
5849 RawObj2Ty, IsRValRef1);
5850 Args2.push_back(Obj2Ty);
5854 if (NonStaticMethod1 && Method1->hasCXXExplicitFunctionObjectParameter())
5859 Args1.insert(Args1.end(), Params1Begin, Proto1->
param_type_end());
5860 Args2.insert(Args2.end(), Params2Begin, Proto2->param_type_end());
5865 Args1.resize(std::min(Args1.size(), NumComparedArguments));
5866 Args2.resize(std::min(Args2.size(), NumComparedArguments));
5869 std::reverse(Args2.begin(), Args2.end());
5871 assert(!
Reversed &&
"Only call context could have reversed arguments");
5874 Args2, Args2Offset);
5876 Args1, Args1Offset);
5880 if (Better1 != Better2)
5881 return Better1 ? FT1 : FT2;
5883 if (!Better1 && !Better2)
5892 Param1.reserve(FD1->
param_size() + ShouldConvert1);
5894 Param1.push_back(Obj1Ty);
5896 Param1.push_back(
P->getType());
5899 Param2.reserve(FD2->
param_size() + ShouldConvert2);
5901 Param2.push_back(Obj2Ty);
5903 Param2.push_back(
P->getType());
5905 unsigned NumParams1 = Param1.size();
5906 unsigned NumParams2 = Param2.size();
5912 if (Variadic1 != Variadic2) {
5913 if (Variadic1 && NumParams1 > NumParams2)
5915 if (Variadic2 && NumParams2 > NumParams1)
5921 for (
int i = 0, e = std::min(NumParams1, NumParams2); i < e; ++i) {
5922 QualType T1 = Param1[i].getCanonicalType();
5923 QualType T2 = Param2[i].getCanonicalType();
5924 auto *TST1 = dyn_cast<TemplateSpecializationType>(T1);
5925 auto *TST2 = dyn_cast<TemplateSpecializationType>(T2);
5930 assert(TST1->template_arguments().size() ==
5931 TST2->template_arguments().size());
5936 bool IsPackExpansion1 =
5938 bool IsPackExpansion2 =
5940 if (PackSize1 != PackSize2 && IsPackExpansion1 != IsPackExpansion2) {
5941 if (PackSize1 > PackSize2 && IsPackExpansion1)
5943 if (PackSize1 < PackSize2 && IsPackExpansion2)
5965 if (TPL1->
size() != TPL2->
size() || NumParams1 != NumParams2)
5981 for (
unsigned i = 0; i < NumParams1; ++i)
5997 bool AtLeastAsConstrained1, AtLeastAsConstrained2;
6002 if (AtLeastAsConstrained1 == AtLeastAsConstrained2)
6004 return AtLeastAsConstrained1 ? FT1 : FT2;
6012 bool Complain,
QualType TargetType) {
6013 if (SpecBegin == SpecEnd) {
6021 if (SpecBegin + 1 == SpecEnd)
6028 = cast<FunctionDecl>(*Best)->getPrimaryTemplate();
6029 assert(BestTemplate &&
"Not a function template specialization?");
6032 = cast<FunctionDecl>(*I)->getPrimaryTemplate();
6033 assert(Challenger &&
"Not a function template specialization?");
6038 BestTemplate = Challenger;
6044 bool Ambiguous =
false;
6047 = cast<FunctionDecl>(*I)->getPrimaryTemplate();
6069 const auto *FD = cast<FunctionDecl>(*I);
6071 FD->getPrimaryTemplate()->getTemplateParameters(),
6072 *FD->getTemplateSpecializationArgs());
6073 if (!TargetType.
isNull())
6075 Diag((*I)->getLocation(), PD);
6085 "not for function templates");
6087 isa<CXXConversionDecl>(FD1));
6089 isa<CXXConversionDecl>(FD2));
6102 bool AtLeastAsConstrained1, AtLeastAsConstrained2;
6107 if (AtLeastAsConstrained1 == AtLeastAsConstrained2)
6109 return AtLeastAsConstrained1 ? FD1 : FD2;
6119template<
typename TemplateLikeDecl>
6121 TemplateLikeDecl *P2,
6150 Deduced.resize(P2->getTemplateParameters()->size());
6152 S, P2->getTemplateParameters(), T2, T1, Info, Deduced,
TDF_None,
6153 PartialOrderingKind::Call,
false,
6164 const auto *TST1 = cast<TemplateSpecializationType>(T1);
6165 bool AtLeastAsSpecialized;
6167 AtLeastAsSpecialized =
6168 FinishTemplateArgumentDeduction(
6169 S, P2, true, TST1->template_arguments(),
6170 Deduced, Info) == TemplateDeductionResult::Success;
6172 return AtLeastAsSpecialized;
6179 template <
typename T1,
typename T2,
6180 std::enable_if_t<std::is_same_v<T1, T2>,
bool> =
true>
6181 T2 *operator()(T1 *, T2 *P2) {
6184 template <
typename T1,
typename T2,
6185 std::enable_if_t<!std::is_same_v<T1, T2>,
bool> =
true>
6186 T1 *operator()(T1 *, T2 *) {
6192struct TemplateArgumentListAreEqual {
6194 TemplateArgumentListAreEqual(
ASTContext &Ctx) : Ctx(Ctx) {}
6196 template <
typename T1,
typename T2,
6197 std::enable_if_t<std::is_same_v<T1, T2>,
bool> =
true>
6198 bool operator()(T1 *PS1, T2 *PS2) {
6200 Args2 = PS2->getTemplateArgs().asArray();
6202 for (
unsigned I = 0,
E = Args1.size(); I <
E; ++I) {
6206 llvm::FoldingSetNodeID IDA, IDB;
6207 Args1[I].Profile(IDA, Ctx);
6208 Args2[I].Profile(IDB, Ctx);
6215 template <
typename T1,
typename T2,
6216 std::enable_if_t<!std::is_same_v<T1, T2>,
bool> =
true>
6217 bool operator()(T1 *Spec, T2 *Primary) {
6219 Args2 = Primary->getInjectedTemplateArgs(Ctx);
6221 for (
unsigned I = 0,
E = Args1.size(); I <
E; ++I) {
6225 llvm::FoldingSetNodeID IDA, IDB;
6226 Args1[I].Profile(IDA, Ctx);
6260template <
typename TemplateLikeDecl,
typename PrimaryDel>
6261static TemplateLikeDecl *
6264 constexpr bool IsMoreSpecialThanPrimaryCheck =
6265 !std::is_same_v<TemplateLikeDecl, PrimaryDel>;
6268 if (IsMoreSpecialThanPrimaryCheck && !Better1)
6272 if (IsMoreSpecialThanPrimaryCheck && !Better2)
6278 if (Better1 != Better2)
6279 return Better1 ? P1 : GetP2()(P1, P2);
6281 if (!Better1 && !Better2)
6286 auto *TST1 = cast<TemplateSpecializationType>(T1);
6287 auto *TST2 = cast<TemplateSpecializationType>(T2);
6290 assert(TST1->template_arguments().size() ==
6291 TST2->template_arguments().size());
6296 bool IsPackExpansion1 =
6298 bool IsPackExpansion2 =
6300 if (PackSize1 != PackSize2 && IsPackExpansion1 != IsPackExpansion2) {
6301 if (PackSize1 > PackSize2 && IsPackExpansion1)
6302 return GetP2()(P1, P2);
6303 if (PackSize1 < PackSize2 && IsPackExpansion2)
6332 if (!TemplateArgumentListAreEqual(S.
getASTContext())(P1, P2))
6336 P1->getAssociatedConstraints(AC1);
6337 P2->getAssociatedConstraints(AC2);
6338 bool AtLeastAsConstrained1, AtLeastAsConstrained2;
6340 (IsMoreSpecialThanPrimaryCheck && !AtLeastAsConstrained1))
6344 if (AtLeastAsConstrained1 == AtLeastAsConstrained2)
6346 return AtLeastAsConstrained1 ? P1 : GetP2()(P1, P2);
6381 "the partial specializations being compared should specialize"
6382 " the same template.");
6438 for (
unsigned I = 0, N =
P->size(); I != N; ++I) {
6447 Arg,
QualType(),
P->getParam(I)->getLocation()));
6457 SugaredPArgs, PArgs,
6468 Deduced.resize(A->
size());
6484 IsDeduced ? PackFold::ArgumentToParameter
6485 : PackFold::ParameterToArgument,
6496 bool AtLeastAsSpecialized;
6498 AtLeastAsSpecialized =
6499 ::FinishTemplateArgumentDeduction(
6500 *this, AArg, true, PArgs, Deduced, Info) ==
6501 TemplateDeductionResult::Success;
6503 return AtLeastAsSpecialized;
6508 llvm::SmallBitVector &
Used;
6511 MarkUsedTemplateParameterVisitor(llvm::SmallBitVector &
Used,
6516 if (
T->getDepth() == Depth)
6517 Used[
T->getIndex()] =
true;
6521 bool TraverseTemplateName(
TemplateName Template)
override {
6522 if (
auto *TTP = llvm::dyn_cast_or_null<TemplateTemplateParmDecl>(
6524 if (TTP->getDepth() == Depth)
6525 Used[TTP->getIndex()] =
true;
6531 if (
auto *NTTP = dyn_cast<NonTypeTemplateParmDecl>(
E->getDecl()))
6532 if (NTTP->getDepth() == Depth)
6533 Used[NTTP->getIndex()] =
true;
6546 llvm::SmallBitVector &
Used) {
6548 MarkUsedTemplateParameterVisitor(
Used, Depth)
6549 .TraverseStmt(
const_cast<Expr *
>(
E));
6555 E = Expansion->getPattern();
6577 llvm::SmallBitVector &
Used) {
6584 OnlyDeduced, Depth,
Used);
6594 llvm::SmallBitVector &
Used) {
6595 if (
TemplateDecl *Template = Name.getAsTemplateDecl()) {
6597 = dyn_cast<TemplateTemplateParmDecl>(Template)) {
6598 if (TTP->getDepth() == Depth)
6599 Used[TTP->getIndex()] =
true;
6618 llvm::SmallBitVector &
Used) {
6636 case Type::BlockPointer:
6644 case Type::LValueReference:
6645 case Type::RValueReference:
6653 case Type::MemberPointer: {
6658 OnlyDeduced, Depth,
Used);
6662 case Type::DependentSizedArray:
6664 cast<DependentSizedArrayType>(
T)->getSizeExpr(),
6665 OnlyDeduced, Depth,
Used);
6669 case Type::ConstantArray:
6670 case Type::IncompleteArray:
6671 case Type::ArrayParameter:
6673 cast<ArrayType>(
T)->getElementType(),
6674 OnlyDeduced, Depth,
Used);
6677 case Type::ExtVector:
6679 cast<VectorType>(
T)->getElementType(),
6680 OnlyDeduced, Depth,
Used);
6683 case Type::DependentVector: {
6684 const auto *VecType = cast<DependentVectorType>(
T);
6691 case Type::DependentSizedExtVector: {
6693 = cast<DependentSizedExtVectorType>(
T);
6701 case Type::DependentAddressSpace: {
6703 cast<DependentAddressSpaceType>(
T);
6705 OnlyDeduced, Depth,
Used);
6708 OnlyDeduced, Depth,
Used);
6712 case Type::ConstantMatrix: {
6719 case Type::DependentSizedMatrix: {
6730 case Type::FunctionProto: {
6734 for (
unsigned I = 0, N = Proto->
getNumParams(); I != N; ++I) {
6739 if (!OnlyDeduced || I + 1 == N ||
6757 case Type::TemplateTypeParm: {
6764 case Type::SubstTemplateTypeParmPack: {
6766 = cast<SubstTemplateTypeParmPackType>(
T);
6770 OnlyDeduced, Depth,
Used);
6774 case Type::InjectedClassName:
6775 T = cast<InjectedClassNameType>(
T)->getInjectedSpecializationType();
6778 case Type::TemplateSpecialization: {
6780 = cast<TemplateSpecializationType>(
T);
6800 cast<ComplexType>(
T)->getElementType(),
6801 OnlyDeduced, Depth,
Used);
6807 cast<AtomicType>(
T)->getValueType(),
6808 OnlyDeduced, Depth,
Used);
6811 case Type::DependentName:
6814 cast<DependentNameType>(
T)->getQualifier(),
6815 OnlyDeduced, Depth,
Used);
6818 case Type::DependentTemplateSpecialization: {
6832 = cast<DependentTemplateSpecializationType>(
T);
6835 OnlyDeduced, Depth,
Used);
6845 OnlyDeduced, Depth,
Used);
6848 case Type::TypeOfExpr:
6851 cast<TypeOfExprType>(
T)->getUnderlyingExpr(),
6852 OnlyDeduced, Depth,
Used);
6855 case Type::Decltype:
6858 cast<DecltypeType>(
T)->getUnderlyingExpr(),
6859 OnlyDeduced, Depth,
Used);
6862 case Type::PackIndexing:
6865 OnlyDeduced, Depth,
Used);
6867 OnlyDeduced, Depth,
Used);
6871 case Type::UnaryTransform:
6875 OnlyDeduced, Depth,
Used);
6878 case Type::PackExpansion:
6880 cast<PackExpansionType>(
T)->getPattern(),
6881 OnlyDeduced, Depth,
Used);
6885 case Type::DeducedTemplateSpecialization:
6887 cast<DeducedType>(
T)->getDeducedType(),
6888 OnlyDeduced, Depth,
Used);
6890 case Type::DependentBitInt:
6892 cast<DependentBitIntType>(
T)->getNumBitsExpr(),
6893 OnlyDeduced, Depth,
Used);
6896 case Type::HLSLAttributedResource:
6898 Ctx, cast<HLSLAttributedResourceType>(
T)->getWrappedType(), OnlyDeduced,
6900 if (cast<HLSLAttributedResourceType>(
T)->hasContainedType())
6902 Ctx, cast<HLSLAttributedResourceType>(
T)->getContainedType(),
6903 OnlyDeduced, Depth,
Used);
6908 case Type::VariableArray:
6909 case Type::FunctionNoProto:
6912 case Type::ObjCInterface:
6913 case Type::ObjCObject:
6914 case Type::ObjCObjectPointer:
6915 case Type::UnresolvedUsing:
6918#define TYPE(Class, Base)
6919#define ABSTRACT_TYPE(Class, Base)
6920#define DEPENDENT_TYPE(Class, Base)
6921#define NON_CANONICAL_TYPE(Class, Base) case Type::Class:
6922#include "clang/AST/TypeNodes.inc"
6934 llvm::SmallBitVector &
Used) {
6952 OnlyDeduced, Depth,
Used);
6970 llvm::SmallBitVector &
Used) {
6976 bool OnlyDeduced,
unsigned Depth,
6977 llvm::SmallBitVector &
Used) {
6986 for (
unsigned I = 0, N = TemplateArgs.
size(); I != N; ++I)
6993 llvm::SmallBitVector &Deduced) {
6997 Deduced.resize(TemplateParams->
size());
7000 for (
unsigned I = 0, N =
Function->getNumParams(); I != N; ++I)
7002 true, TemplateParams->
getDepth(), Deduced);
7013 llvm::SmallBitVector Deduced(TemplateParams->
size());
7017 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 bool ConvertDeducedTemplateArgument(Sema &S, NamedDecl *Param, DeducedTemplateArgument Arg, NamedDecl *Template, TemplateDeductionInfo &Info, bool IsDeduced, SmallVectorImpl< TemplateArgument > &SugaredOutput, SmallVectorImpl< TemplateArgument > &CanonicalOutput)
Convert the given deduced template argument and add it to the set of fully-converted template argumen...
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...
static bool DeducedArgsNeedReplacement(TemplateDeclT *Template)
static TemplateDeductionResult CheckDeductionConsistency(Sema &S, FunctionTemplateDecl *FTD, int ArgIdx, QualType P, QualType A, ArrayRef< TemplateArgument > DeducedArgs, bool CheckConsistency)
static QualType ResolveOverloadForDeduction(Sema &S, TemplateParameterList *TemplateParams, Expr *Arg, QualType ParamType, bool ParamWasReference, TemplateSpecCandidateSet *FailedTSC=nullptr)
Apply the deduction rules for overload sets.
static bool IsPossiblyOpaquelyQualifiedType(QualType T)
Determines whether the given type is an opaque type that might be more qualified when instantiated.
static const TemplateSpecializationType * getLastTemplateSpecType(QualType QT)
Deduce the template arguments by comparing the template parameter type (which is a template-id) with ...
static std::enable_if_t< IsPartialSpecialization< T >::value, TemplateDeductionResult > FinishTemplateArgumentDeduction(Sema &S, T *Partial, bool IsPartialOrdering, ArrayRef< TemplateArgument > TemplateArgs, SmallVectorImpl< DeducedTemplateArgument > &Deduced, TemplateDeductionInfo &Info)
Complete template argument deduction for a partial specialization.
static TemplateDeductionResult instantiateExplicitSpecifierDeferred(Sema &S, FunctionDecl *Specialization, const MultiLevelTemplateArgumentList &SubstArgs, TemplateDeductionInfo &Info, FunctionTemplateDecl *FunctionTemplate, ArrayRef< TemplateArgument > DeducedArgs)
static bool CheckDeducedPlaceholderConstraints(Sema &S, const AutoType &Type, AutoTypeLoc TypeLoc, QualType Deduced)
static bool IsPossiblyOpaquelyQualifiedTypeInternal(const Type *T)
static bool hasDeducibleTemplateParameters(Sema &S, FunctionTemplateDecl *FunctionTemplate, QualType T)
static bool isForwardingReference(QualType Param, unsigned FirstInnerIndex)
Determine whether a type denotes a forwarding reference.
bool DeducedArgsNeedReplacement< VarTemplatePartialSpecializationDecl >(VarTemplatePartialSpecializationDecl *Spec)
static TemplateDeductionResult ConvertDeducedTemplateArguments(Sema &S, TemplateDeclT *Template, bool IsDeduced, SmallVectorImpl< DeducedTemplateArgument > &Deduced, TemplateDeductionInfo &Info, SmallVectorImpl< TemplateArgument > &SugaredBuilder, SmallVectorImpl< TemplateArgument > &CanonicalBuilder, LocalInstantiationScope *CurrentInstantiationScope=nullptr, unsigned NumAlreadyConverted=0, bool *IsIncomplete=nullptr)
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...
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.
QualType SubstAutoType(QualType TypeWithAuto, QualType Replacement)
Substitute Replacement for auto in TypeWithAuto.
LocalInstantiationScope * CurrentInstantiationScope
The current instantiation scope used to store local variables.
TemplateArgumentLoc getTrivialTemplateArgumentLoc(const TemplateArgument &Arg, QualType NTTPType, SourceLocation Loc, NamedDecl *TemplateParam=nullptr)
Allocate a TemplateArgumentLoc where all locations have been initialized to the given location.
TemplateDeductionResult DeduceTemplateArgumentsFromType(TemplateDecl *TD, QualType FromType, sema::TemplateDeductionInfo &Info)
Deduce the template arguments of the given template from FromType.
QualType ReplaceAutoType(QualType TypeWithAuto, QualType Replacement)
Completely replace the auto in TypeWithAuto by Replacement.
bool TemplateParameterListsAreEqual(const TemplateCompareNewDeclInfo &NewInstFrom, TemplateParameterList *New, const NamedDecl *OldInstFrom, TemplateParameterList *Old, bool Complain, TemplateParameterListEqualKind Kind, SourceLocation TemplateArgLoc=SourceLocation())
Determine whether the given template parameter lists are equivalent.
TemplateArgumentLoc SubstDefaultTemplateArgumentIfAvailable(TemplateDecl *Template, SourceLocation TemplateLoc, SourceLocation RAngleLoc, Decl *Param, ArrayRef< TemplateArgument > SugaredConverted, ArrayRef< TemplateArgument > CanonicalConverted, bool &HasDefaultArg)
If the given template parameter has a default template argument, substitute into that default templat...
ClassTemplatePartialSpecializationDecl * getMoreSpecializedPartialSpecialization(ClassTemplatePartialSpecializationDecl *PS1, ClassTemplatePartialSpecializationDecl *PS2, SourceLocation Loc)
Returns the more specialized class template partial specialization according to the rules of partial ...
FunctionDecl * getMoreConstrainedFunction(FunctionDecl *FD1, FunctionDecl *FD2)
Returns the more constrained function according to the rules of partial ordering by constraints (C++ ...
FunctionDecl * InstantiateFunctionDeclaration(FunctionTemplateDecl *FTD, const TemplateArgumentList *Args, SourceLocation Loc, CodeSynthesisContext::SynthesisKind CSC=CodeSynthesisContext::ExplicitTemplateArgumentSubstitution)
Instantiate (or find existing instantiation of) a function template with a given set of template argu...
QualType BuildStdInitializerList(QualType Element, SourceLocation Loc)
Looks for the std::initializer_list template and instantiates it with Element, or emits an error if i...
ExpressionEvaluationContextRecord & parentEvaluationContext()
@ 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.
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),...
bool CheckTemplateArgument(NamedDecl *Param, TemplateArgumentLoc &Arg, NamedDecl *Template, SourceLocation TemplateLoc, SourceLocation RAngleLoc, unsigned ArgumentPackIndex, SmallVectorImpl< TemplateArgument > &SugaredConverted, SmallVectorImpl< TemplateArgument > &CanonicalConverted, CheckTemplateArgumentKind CTAK)
Check that the given template argument corresponds to the given template parameter.
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)
Check that the given template arguments can be provided to the given template, converting the argumen...
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)
bool CheckFunctionTemplateConstraints(SourceLocation PointOfInstantiation, FunctionDecl *Decl, ArrayRef< TemplateArgument > TemplateArgs, ConstraintSatisfaction &Satisfaction)
TemplateDeductionResult FinishTemplateArgumentDeduction(FunctionTemplateDecl *FunctionTemplate, SmallVectorImpl< DeducedTemplateArgument > &Deduced, unsigned NumExplicitlySpecified, FunctionDecl *&Specialization, sema::TemplateDeductionInfo &Info, SmallVectorImpl< OriginalCallArg > const *OriginalCallArgs=nullptr, bool PartialOverloading=false, llvm::function_ref< bool()> CheckNonDependent=[] { return false;})
Finish template argument deduction for a function template, checking the deduced template arguments f...
void runWithSufficientStackSpace(SourceLocation Loc, llvm::function_ref< void()> Fn)
Run some code with "sufficient" stack space.
bool isMoreSpecializedThanPrimary(ClassTemplatePartialSpecializationDecl *T, sema::TemplateDeductionInfo &Info)
bool isTemplateTemplateParameterAtLeastAsSpecializedAs(TemplateParameterList *PParam, TemplateDecl *AArg, const DefaultArguments &DefaultArgs, SourceLocation Loc, bool IsDeduced)
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()
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.
ConstraintSatisfaction AssociatedConstraintsSatisfaction
The constraint satisfaction details resulting from the associated constraints satisfaction tests.
unsigned CallArgIndex
The index of the function argument that caused a deduction failure.
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 (&&).
unsigned toTargetAddressSpace(LangAS AS)
bool isLambdaCallOperator(const CXXMethodDecl *MD)
@ Result
The result type of a method or function.
std::pair< unsigned, unsigned > getDepthAndIndex(const NamedDecl *ND)
Retrieve the depth and index of a template parameter.
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.
@ 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.
@ 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.