37#include "llvm/Support/ErrorHandling.h"
38#include "llvm/Support/TimeProfiler.h"
51 const Decl *NextDecl =
nullptr;
53 bool ClearRelativeToPrimary =
true;
54 static Response Done() {
59 static Response ChangeDecl(
const Decl *ND) {
64 static Response ChangeDecl(
const DeclContext *Ctx) {
70 static Response UseNextDecl(
const Decl *CurDecl) {
74 static Response DontClearRelativeToPrimaryNextDecl(
const Decl *CurDecl) {
75 Response R = Response::UseNextDecl(CurDecl);
76 R.ClearRelativeToPrimary =
false;
84 bool SkipForSpecialization) {
88 return Response::DontClearRelativeToPrimaryNextDecl(VarTemplSpec);
92 !isa<VarTemplatePartialSpecializationDecl>(VarTemplSpec))
93 return Response::Done();
98 llvm::PointerUnion<VarTemplateDecl *, VarTemplatePartialSpecializationDecl *>
102 if (!SkipForSpecialization)
103 Result.addOuterTemplateArguments(
106 if (Partial->isMemberSpecialization())
107 return Response::Done();
110 if (!SkipForSpecialization)
111 Result.addOuterTemplateArguments(
115 return Response::Done();
117 return Response::DontClearRelativeToPrimaryNextDecl(VarTemplSpec);
129 for (
unsigned I = 0, N = TTP->
getDepth() + 1; I != N; ++I)
130 Result.addOuterTemplateArguments(std::nullopt);
131 return Response::Done();
138 bool SkipForSpecialization) {
142 !isa<ClassTemplatePartialSpecializationDecl>(ClassTemplSpec))
143 return Response::Done();
145 if (!SkipForSpecialization)
146 Result.addOuterTemplateArguments(
155 return Response::Done();
157 return Response::UseNextDecl(ClassTemplSpec);
163 bool ForConstraintInstantiation) {
165 if (!RelativeToPrimary &&
166 Function->getTemplateSpecializationKindForInstantiation() ==
168 return Response::Done();
170 if (!RelativeToPrimary &&
175 return Response::UseNextDecl(Function);
177 Function->getTemplateSpecializationArgs()) {
179 Result.addOuterTemplateArguments(
const_cast<FunctionDecl *
>(Function),
180 TemplateArgs->asArray(),
185 assert(Function->getPrimaryTemplate() &&
"No function template?");
186 if (Function->getPrimaryTemplate()->isMemberSpecialization())
187 return Response::Done();
190 if (!ForConstraintInstantiation &&
192 return Response::Done();
194 }
else if (Function->getDescribedFunctionTemplate()) {
196 (ForConstraintInstantiation || Result.getNumSubstitutedLevels() == 0) &&
197 "Outer template not instantiated?");
203 if ((Function->getFriendObjectKind() || Function->isLocalExternDecl()) &&
204 Function->getNonTransparentDeclContext()->isFileContext() &&
206 return Response::ChangeDecl(Function->getLexicalDeclContext());
208 return Response::UseNextDecl(Function);
214 bool ForConstraintInstantiation) {
217 (ForConstraintInstantiation || Result.getNumSubstitutedLevels() == 0) &&
218 "Outer template not instantiated?");
219 if (ClassTemplate->isMemberSpecialization())
220 return Response::Done();
221 if (ForConstraintInstantiation) {
224 ->getInjectedSpecializationType();
225 const auto *InjectedType = cast<TemplateSpecializationType>(Injected);
226 Result.addOuterTemplateArguments(
const_cast<CXXRecordDecl *
>(Rec),
227 InjectedType->template_arguments(),
235 if (ForConstraintInstantiation && IsFriend &&
244 return Response::ChangeDecl(LCD);
246 return Response::UseNextDecl(Rec);
249Response HandleImplicitConceptSpecializationDecl(
252 Result.addOuterTemplateArguments(
256 return Response::UseNextDecl(CSD);
259Response HandleGenericDeclContext(
const Decl *CurDecl) {
260 return Response::UseNextDecl(CurDecl);
292 bool ForConstraintInstantiation,
bool SkipForSpecialization) {
293 assert(ND &&
"Can't find arguments for a decl if one isn't provided");
301 const Decl *CurDecl = ND;
306 if (
const auto *VarTemplSpec =
307 dyn_cast<VarTemplateSpecializationDecl>(CurDecl)) {
308 R = HandleVarTemplateSpec(VarTemplSpec,
Result, SkipForSpecialization);
309 }
else if (
const auto *ClassTemplSpec =
310 dyn_cast<ClassTemplateSpecializationDecl>(CurDecl)) {
311 R = HandleClassTemplateSpec(ClassTemplSpec,
Result,
312 SkipForSpecialization);
313 }
else if (
const auto *Function = dyn_cast<FunctionDecl>(CurDecl)) {
314 R = HandleFunction(Function,
Result, Pattern, RelativeToPrimary,
315 ForConstraintInstantiation);
316 }
else if (
const auto *Rec = dyn_cast<CXXRecordDecl>(CurDecl)) {
317 R = HandleRecordDecl(Rec,
Result,
Context, ForConstraintInstantiation);
318 }
else if (
const auto *CSD =
319 dyn_cast<ImplicitConceptSpecializationDecl>(CurDecl)) {
320 R = HandleImplicitConceptSpecializationDecl(CSD,
Result);
321 }
else if (!isa<DeclContext>(CurDecl)) {
322 R = Response::DontClearRelativeToPrimaryNextDecl(CurDecl);
324 if (
const auto *TTP = dyn_cast<TemplateTemplateParmDecl>(CurDecl)) {
325 R = HandleDefaultTempArgIntoTempTempParam(TTP,
Result);
329 R = HandleGenericDeclContext(CurDecl);
334 if (R.ClearRelativeToPrimary)
335 RelativeToPrimary =
false;
337 CurDecl = R.NextDecl;
377 llvm_unreachable(
"Invalid SynthesisKind!");
407 AlreadyInstantiating = !Inst.Entity ?
false :
409 .insert({Inst.Entity->getCanonicalDecl(), Inst.Kind})
420 PointOfInstantiation, InstantiationRange, Entity) {}
427 PointOfInstantiation, InstantiationRange, Entity) {}
437 Template, TemplateArgs) {}
447 TemplateArgs, &DeductionInfo) {
461 PointOfInstantiation, InstantiationRange, Template, nullptr,
462 TemplateArgs, &DeductionInfo) {}
472 PointOfInstantiation, InstantiationRange, PartialSpec, nullptr,
473 TemplateArgs, &DeductionInfo) {}
483 PointOfInstantiation, InstantiationRange, PartialSpec, nullptr,
484 TemplateArgs, &DeductionInfo) {}
492 PointOfInstantiation, InstantiationRange, Param, nullptr,
502 PointOfInstantiation, InstantiationRange, Param, Template,
512 PointOfInstantiation, InstantiationRange, Param, Template,
521 PointOfInstantiation, InstantiationRange, Param, Template,
530 PointOfInstantiation, InstantiationRange, nullptr,
531 nullptr,
std::nullopt, &DeductionInfo) {
540 PointOfInstantiation, InstantiationRange, nullptr,
541 nullptr,
std::nullopt) {}
548 PointOfInstantiation, InstantiationRange, nullptr,
549 nullptr,
std::nullopt, &DeductionInfo) {
558 PointOfInstantiation, InstantiationRange, Template, nullptr,
567 PointOfInstantiation, InstantiationRange, Template, nullptr,
568 {}, &DeductionInfo) {}
576 PointOfInstantiation, InstantiationRange, Template) {}
584 PointOfInstantiation, InstantiationRange, Template) {}
604 if (!Active.isInstantiationRecord()) {
614 "forgot to remove a lookup module for a template instantiation");
633 if (!AlreadyInstantiating) {
637 {Active.Entity->getCanonicalDecl(), Active.Kind});
651 llvm::raw_string_ostream
OS(
Result);
652 llvm::ListSeparator Comma;
653 for (
const Expr *Arg : Args) {
655 Arg->IgnoreParens()->printPretty(
OS,
nullptr,
661bool Sema::InstantiatingTemplate::CheckInstantiationDepth(
671 SemaRef.
Diag(PointOfInstantiation,
672 diag::err_template_recursion_depth_exceeded)
674 << InstantiationRange;
675 SemaRef.
Diag(PointOfInstantiation, diag::note_template_recursion_depth)
687 SkipStart = Limit / 2 + Limit % 2;
692 unsigned InstantiationIdx = 0;
697 ++Active, ++InstantiationIdx) {
699 if (InstantiationIdx >= SkipStart && InstantiationIdx < SkipEnd) {
700 if (InstantiationIdx == SkipStart) {
703 diag::note_instantiation_contexts_suppressed)
709 switch (Active->Kind) {
711 Decl *D = Active->Entity;
713 unsigned DiagID = diag::note_template_member_class_here;
714 if (isa<ClassTemplateSpecializationDecl>(Record))
715 DiagID = diag::note_template_class_instantiation_here;
717 << Record << Active->InstantiationRange;
718 }
else if (
FunctionDecl *Function = dyn_cast<FunctionDecl>(D)) {
720 if (Function->getPrimaryTemplate())
721 DiagID = diag::note_function_template_spec_here;
723 DiagID = diag::note_template_member_function_here;
726 << Active->InstantiationRange;
727 }
else if (
VarDecl *VD = dyn_cast<VarDecl>(D)) {
729 VD->isStaticDataMember()?
730 diag::note_template_static_data_member_def_here
731 : diag::note_template_variable_def_here)
733 << Active->InstantiationRange;
734 }
else if (
EnumDecl *ED = dyn_cast<EnumDecl>(D)) {
736 diag::note_template_enum_def_here)
738 << Active->InstantiationRange;
739 }
else if (
FieldDecl *FD = dyn_cast<FieldDecl>(D)) {
741 diag::note_template_nsdmi_here)
742 << FD << Active->InstantiationRange;
745 diag::note_template_type_alias_instantiation_here)
746 << cast<TypeAliasTemplateDecl>(D)
747 << Active->InstantiationRange;
753 TemplateDecl *Template = cast<TemplateDecl>(Active->Template);
755 llvm::raw_svector_ostream
OS(TemplateArgsStr);
760 diag::note_default_arg_instantiation_here)
762 << Active->InstantiationRange;
769 diag::note_explicit_template_arg_substitution_here)
772 Active->TemplateArgs,
773 Active->NumTemplateArgs)
774 << Active->InstantiationRange;
780 dyn_cast<FunctionTemplateDecl>(Active->Entity)) {
782 diag::note_function_template_deduction_instantiation_here)
785 Active->TemplateArgs,
786 Active->NumTemplateArgs)
787 << Active->InstantiationRange;
789 bool IsVar = isa<VarTemplateDecl>(Active->Entity) ||
790 isa<VarTemplateSpecializationDecl>(Active->Entity);
791 bool IsTemplate =
false;
793 if (
auto *D = dyn_cast<TemplateDecl>(Active->Entity)) {
795 Params = D->getTemplateParameters();
796 }
else if (
auto *D = dyn_cast<ClassTemplatePartialSpecializationDecl>(
798 Params = D->getTemplateParameters();
799 }
else if (
auto *D = dyn_cast<VarTemplatePartialSpecializationDecl>(
801 Params = D->getTemplateParameters();
803 llvm_unreachable(
"unexpected template kind");
807 diag::note_deduced_template_arg_substitution_here)
808 << IsVar << IsTemplate << cast<NamedDecl>(Active->Entity)
810 Active->NumTemplateArgs)
811 << Active->InstantiationRange;
817 ParmVarDecl *Param = cast<ParmVarDecl>(Active->Entity);
821 llvm::raw_svector_ostream
OS(TemplateArgsStr);
826 diag::note_default_function_arg_instantiation_here)
828 << Active->InstantiationRange;
833 NamedDecl *Parm = cast<NamedDecl>(Active->Entity);
836 Name = std::string(
" '") + Parm->
getName().str() +
"'";
839 if (
TemplateDecl *Template = dyn_cast<TemplateDecl>(Active->Template))
840 TemplateParams = Template->getTemplateParameters();
843 cast<ClassTemplatePartialSpecializationDecl>(Active->Template)
844 ->getTemplateParameters();
846 diag::note_prior_template_arg_substitution)
847 << isa<TemplateTemplateParmDecl>(Parm)
850 Active->TemplateArgs,
851 Active->NumTemplateArgs)
852 << Active->InstantiationRange;
858 if (
TemplateDecl *Template = dyn_cast<TemplateDecl>(Active->Template))
859 TemplateParams = Template->getTemplateParameters();
862 cast<ClassTemplatePartialSpecializationDecl>(Active->Template)
863 ->getTemplateParameters();
866 diag::note_template_default_arg_checking)
868 Active->TemplateArgs,
869 Active->NumTemplateArgs)
870 << Active->InstantiationRange;
876 diag::note_evaluating_exception_spec_here)
877 << cast<FunctionDecl>(Active->Entity);
882 diag::note_template_exception_spec_instantiation_here)
883 << cast<FunctionDecl>(Active->Entity)
884 << Active->InstantiationRange;
889 diag::note_template_requirement_instantiation_here)
890 << Active->InstantiationRange;
894 diag::note_template_requirement_params_instantiation_here)
895 << Active->InstantiationRange;
900 diag::note_nested_requirement_here)
901 << Active->InstantiationRange;
906 diag::note_in_declaration_of_implicit_special_member)
907 << cast<CXXRecordDecl>(Active->Entity) << Active->SpecialMember;
912 diag::note_in_declaration_of_implicit_equality_comparison);
918 auto *FD = dyn_cast<FunctionDecl>(Active->Entity);
922 auto *MD = cast<CXXMethodDecl>(FD);
924 diag::note_member_synthesized_at)
929 diag::note_comparison_synthesized_at)
932 cast<CXXRecordDecl>(FD->getLexicalDeclContext()));
939 diag::note_rewriting_operator_as_spaceship);
944 diag::note_in_binding_decl_init)
945 << cast<BindingDecl>(Active->Entity);
950 diag::note_due_to_dllexported_class)
951 << cast<CXXRecordDecl>(Active->Entity) << !
getLangOpts().CPlusPlus11;
956 diag::note_building_builtin_dump_struct_call)
966 if (!Active->Entity) {
968 diag::note_nested_requirement_here)
969 << Active->InstantiationRange;
972 if (isa<ConceptDecl>(Active->Entity))
973 DiagID = diag::note_concept_specialization_here;
974 else if (isa<TemplateDecl>(Active->Entity))
975 DiagID = diag::note_checking_constraints_for_template_id_here;
976 else if (isa<VarTemplatePartialSpecializationDecl>(Active->Entity))
977 DiagID = diag::note_checking_constraints_for_var_spec_id_here;
978 else if (isa<ClassTemplatePartialSpecializationDecl>(Active->Entity))
979 DiagID = diag::note_checking_constraints_for_class_spec_id_here;
981 assert(isa<FunctionDecl>(Active->Entity));
982 DiagID = diag::note_checking_constraints_for_function_here;
985 llvm::raw_svector_ostream
OS(TemplateArgsStr);
987 if (!isa<FunctionDecl>(Active->Entity)) {
991 Diags.
Report(Active->PointOfInstantiation, DiagID) <<
OS.str()
992 << Active->InstantiationRange;
997 diag::note_constraint_substitution_here)
998 << Active->InstantiationRange;
1002 diag::note_constraint_normalization_here)
1003 << cast<NamedDecl>(Active->Entity)->getName()
1004 << Active->InstantiationRange;
1008 diag::note_parameter_mapping_substitution_here)
1009 << Active->InstantiationRange;
1017 return std::optional<TemplateDeductionInfo *>(
nullptr);
1022 Active != ActiveEnd;
1025 switch (Active->Kind) {
1029 if (isa<TypeAliasTemplateDecl>(Active->Entity))
1039 return std::nullopt;
1058 assert(Active->DeductionInfo &&
"Missing deduction info pointer");
1059 return Active->DeductionInfo;
1069 return std::nullopt;
1083 if (Active->SavedInNonInstantiationSFINAEContext)
1084 return std::optional<TemplateDeductionInfo *>(
nullptr);
1087 return std::nullopt;
1094 class TemplateInstantiator :
public TreeTransform<TemplateInstantiator> {
1098 bool EvaluateConstraints =
true;
1103 TemplateInstantiator(
Sema &SemaRef,
1106 : inherited(SemaRef), TemplateArgs(TemplateArgs), Loc(Loc),
1109 void setEvaluateConstraints(
bool B) {
1110 EvaluateConstraints = B;
1112 bool getEvaluateConstraints() {
1113 return EvaluateConstraints;
1121 bool AlreadyTransformed(
QualType T);
1133 this->Entity = Entity;
1136 unsigned TransformTemplateDepth(
unsigned Depth) {
1141 int Index = getSema().ArgumentPackSubstitutionIndex;
1143 return std::nullopt;
1150 bool &ShouldExpand,
bool &RetainExpansion,
1151 std::optional<unsigned> &NumExpansions) {
1152 return getSema().CheckParameterPacksForExpansion(EllipsisLoc,
1153 PatternRange, Unexpanded,
1160 void ExpandingFunctionParameterPack(
ParmVarDecl *Pack) {
1170 unsigned Depth, Index;
1173 Result = TemplateArgs(Depth, Index);
1189 unsigned Depth, Index;
1199 void transformAttrs(
Decl *Old,
Decl *New) {
1206 for (
auto *New : NewDecls)
1208 Old, cast<VarDecl>(New));
1212 assert(NewDecls.size() == 1 &&
1213 "should only have multiple expansions for a pack");
1214 Decl *New = NewDecls.front();
1219 auto *NewMD = dyn_cast<CXXMethodDecl>(New);
1221 auto *OldMD = dyn_cast<CXXMethodDecl>(Old);
1222 if (
auto *NewTD = NewMD->getDescribedFunctionTemplate())
1223 NewTD->setInstantiatedFromMemberTemplate(
1224 OldMD->getDescribedFunctionTemplate());
1226 NewMD->setInstantiationOfMemberFunction(OldMD,
1234 if (
auto *DC = dyn_cast<DeclContext>(Old);
1235 DC && DC->isDependentContext() && DC->isFunctionOrMethod())
1271 NamedDecl *FirstQualifierInScope =
nullptr,
1272 bool AllowInjectedClassName =
false);
1274 const LoopHintAttr *TransformLoopHintAttr(
const LoopHintAttr *LH);
1282 ExprResult TransformSubstNonTypeTemplateParmPackExpr(
1284 ExprResult TransformSubstNonTypeTemplateParmExpr(
1301 return inherited::TransformFunctionProtoType(TLB, TL);
1304 template<
typename Fn>
1309 Fn TransformExceptionSpec);
1312 TransformFunctionTypeParam(
ParmVarDecl *OldParm,
int indexAdjustment,
1313 std::optional<unsigned> NumExpansions,
1314 bool ExpectParameterPack);
1316 using inherited::TransformTemplateTypeParmType;
1321 bool SuppressObjCLifetime);
1323 QualType BuildSubstTemplateTypeParmType(
1325 Decl *AssociatedDecl,
unsigned Index, std::optional<unsigned> PackIndex,
1331 using inherited::TransformSubstTemplateTypeParmPackType;
1335 bool SuppressObjCLifetime);
1340 ExprResult Result = inherited::TransformLambdaExpr(E);
1341 if (Result.isInvalid())
1346 if (!PVD->hasDefaultArg())
1348 Expr *UninstExpr = PVD->getUninstantiatedDefaultArg();
1357 { UninstExpr }, UninstExpr->
getType());
1359 PVD->setDefaultArg(ErrorResult.
get());
1368 ExprResult TransReq = inherited::TransformRequiresExpr(E);
1371 assert(TransReq.
get() != E &&
1372 "Do not change value of isSatisfied for the existing expression. "
1373 "Create a new expression instead.");
1380 if (Trap.hasErrorOccurred())
1386 bool TransformRequiresExprRequirements(
1389 bool SatisfactionDetermined =
false;
1392 if (!SatisfactionDetermined) {
1393 if (
auto *TypeReq = dyn_cast<concepts::TypeRequirement>(Req))
1394 TransReq = TransformTypeRequirement(TypeReq);
1395 else if (
auto *ExprReq = dyn_cast<concepts::ExprRequirement>(Req))
1396 TransReq = TransformExprRequirement(ExprReq);
1398 TransReq = TransformNestedRequirement(
1399 cast<concepts::NestedRequirement>(Req));
1408 SatisfactionDetermined =
true;
1411 Transformed.push_back(TransReq);
1418 if (!OrigTPL || !OrigTPL->
size())
return OrigTPL;
1422 Owner, TemplateArgs);
1423 DeclInstantiator.setEvaluateConstraints(EvaluateConstraints);
1424 return DeclInstantiator.SubstTemplateParams(OrigTPL);
1442 transformNonTypeTemplateParmRef(
Decl *AssociatedDecl,
1445 std::optional<unsigned> PackIndex);
1449bool TemplateInstantiator::AlreadyTransformed(
QualType T) {
1456 getSema().MarkDeclarationsReferencedInType(Loc, T);
1481 TTP->getPosition()))
1486 if (TTP->isParameterPack()) {
1488 "Missing argument pack");
1494 "Wrong kind of template template argument");
1506 Decl *Inst = getSema().SubstDecl(D, getSema().
CurContext, TemplateArgs);
1510 getSema().CurrentInstantiationScope->InstantiatedLocal(D, Inst);
1515TemplateInstantiator::TransformFirstQualifierInScope(
NamedDecl *D,
1529 "Missing argument pack");
1539 return cast_or_null<NamedDecl>(TransformDecl(Loc, D));
1542 return Tag->getDecl();
1545 getSema().Diag(Loc, diag::err_nested_name_spec_non_tag) << T;
1550 return cast_or_null<NamedDecl>(TransformDecl(Loc, D));
1554TemplateInstantiator::RebuildExceptionDecl(
VarDecl *ExceptionDecl,
1560 StartLoc, NameLoc, Name);
1562 getSema().CurrentInstantiationScope->InstantiatedLocal(ExceptionDecl, Var);
1566VarDecl *TemplateInstantiator::RebuildObjCExceptionDecl(
VarDecl *ExceptionDecl,
1569 VarDecl *Var = inherited::RebuildObjCExceptionDecl(ExceptionDecl, TSInfo, T);
1571 getSema().CurrentInstantiationScope->InstantiatedLocal(ExceptionDecl, Var);
1576TemplateInstantiator::RebuildElaboratedType(
SourceLocation KeywordLoc,
1593 SemaRef.
Diag(TagLocation, diag::err_use_with_wrong_tag)
1602 return inherited::RebuildElaboratedType(KeywordLoc, Keyword, QualifierLoc, T);
1605TemplateName TemplateInstantiator::TransformTemplateName(
1608 bool AllowInjectedClassName) {
1610 = dyn_cast_or_null<TemplateTemplateParmDecl>(Name.getAsTemplateDecl())) {
1617 TTP->getPosition()))
1627 "unexpected pack arguments in template rewrite");
1631 "unexpected nontype template argument kind in template rewrite");
1635 auto [AssociatedDecl, Final] =
1637 std::optional<unsigned> PackIndex;
1640 "Missing argument pack");
1646 return getSema().Context.getSubstTemplateTemplateParmPack(
1647 Arg, AssociatedDecl, TTP->
getIndex(), Final);
1650 PackIndex = getPackIndex(Arg);
1655 assert(!Template.
isNull() &&
"Null template template argument");
1657 "template decl to substitute is qualified?");
1661 return getSema().Context.getSubstTemplateTemplateParm(
1662 Template, AssociatedDecl, TTP->
getIndex(), PackIndex);
1667 = Name.getAsSubstTemplateTemplateParmPack()) {
1674 if (SubstPack->getFinal())
1676 return getSema().Context.getSubstTemplateTemplateParm(
1678 SubstPack->getIndex(), getPackIndex(Pack));
1681 return inherited::TransformTemplateName(SS, Name, NameLoc, ObjectType,
1682 FirstQualifierInScope,
1683 AllowInjectedClassName);
1687TemplateInstantiator::TransformPredefinedExpr(
PredefinedExpr *E) {
1695TemplateInstantiator::TransformTemplateParmRefExpr(
DeclRefExpr *E,
1712 "unexpected pack arguments in template rewrite");
1716 "unexpected nontype template argument kind in template rewrite");
1723 std::optional<unsigned> PackIndex;
1726 "Missing argument pack");
1746 PackIndex = getPackIndex(Arg);
1750 return transformNonTypeTemplateParmRef(AssociatedDecl, NTTP, E->
getLocation(),
1755TemplateInstantiator::TransformLoopHintAttr(
const LoopHintAttr *LH) {
1756 Expr *TransformedExpr = getDerived().TransformExpr(LH->getValue()).get();
1758 if (TransformedExpr == LH->getValue())
1767 return LoopHintAttr::CreateImplicit(getSema().
Context, LH->getOption(),
1768 LH->getState(), TransformedExpr, *LH);
1771ExprResult TemplateInstantiator::transformNonTypeTemplateParmRef(
1774 std::optional<unsigned> PackIndex) {
1779 auto SubstParamType = [&] {
1786 T = cast<PackExpansionType>(T)->getPattern();
1790 bool refParam =
false;
1796 Expr *argExpr =
arg.getAsExpr();
1801 QualType paramType = SubstParamType();
1813 VD =
arg.getAsDecl();
1817 VD = cast_or_null<ValueDecl>(
1826 QualType paramType = VD ?
arg.getParamTypeForDecl() :
arg.getNullPtrType();
1827 assert(!paramType.
isNull() &&
"type substitution failed for param type");
1828 assert(!paramType->
isDependentType() &&
"param type still dependent");
1835 arg.getIntegralType()));
1841 Expr *resultExpr = result.
get();
1845 AssociatedDecl, parm->
getIndex(), PackIndex, refParam);
1849TemplateInstantiator::TransformSubstNonTypeTemplateParmPackExpr(
1859 return transformNonTypeTemplateParmRef(
1865TemplateInstantiator::TransformSubstNonTypeTemplateParmExpr(
1868 if (!isa<ConstantExpr>(SubstReplacement.
get()))
1898 SubstReplacement.
get(), SugaredConverted,
1910 return getSema().BuildDeclarationNameExpr(
CXXScopeSpec(), NameInfo, PD);
1921 return RebuildVarDeclRefExpr(VD, E->
getExprLoc());
1943 getSema().MarkFunctionParmPackReferenced(PackExpr);
1948TemplateInstantiator::TransformFunctionParmPackRefExpr(
DeclRefExpr *E,
1951 llvm::PointerUnion<Decl *, DeclArgumentPack *> *Found
1952 = getSema().CurrentInstantiationScope->findInstantiationOf(PD);
1953 assert(Found &&
"no instantiation for parameter pack");
1955 Decl *TransformedDecl;
1956 if (DeclArgumentPack *Pack = Found->dyn_cast<DeclArgumentPack *>()) {
1965 getSema().MarkFunctionParmPackReferenced(PackExpr);
1969 TransformedDecl = (*Pack)[getSema().ArgumentPackSubstitutionIndex];
1971 TransformedDecl = Found->get<
Decl*>();
1975 return RebuildVarDeclRefExpr(cast<VarDecl>(TransformedDecl), E->
getExprLoc());
1979TemplateInstantiator::TransformDeclRefExpr(
DeclRefExpr *E) {
1986 return TransformTemplateParmRefExpr(E, NTTP);
1993 if (
VarDecl *PD = dyn_cast<VarDecl>(D))
1995 return TransformFunctionParmPackRefExpr(E, PD);
1997 return inherited::TransformDeclRefExpr(E);
2000ExprResult TemplateInstantiator::TransformCXXDefaultArgExpr(
2003 getDescribedFunctionTemplate() &&
2004 "Default arg expressions are never formed in dependent cases.");
2010template<
typename Fn>
2015 Fn TransformExceptionSpec) {
2018 return inherited::TransformFunctionProtoType(
2019 TLB, TL, ThisContext, ThisTypeQuals, TransformExceptionSpec);
2022ParmVarDecl *TemplateInstantiator::TransformFunctionTypeParam(
2024 std::optional<unsigned> NumExpansions,
bool ExpectParameterPack) {
2026 OldParm, TemplateArgs, indexAdjustment, NumExpansions,
2027 ExpectParameterPack, EvaluateConstraints);
2033QualType TemplateInstantiator::BuildSubstTemplateTypeParmType(
2035 Decl *AssociatedDecl,
unsigned Index, std::optional<unsigned> PackIndex,
2041 if (SuppressObjCLifetime) {
2054 QualType Result = getSema().Context.getSubstTemplateTypeParmType(
2055 Replacement, AssociatedDecl, Index, PackIndex);
2063TemplateInstantiator::TransformTemplateTypeParmType(
TypeLocBuilder &TLB,
2065 bool SuppressObjCLifetime) {
2089 "unexpected pack arguments in template rewrite");
2093 "unexpected nontype template argument kind in template rewrite");
2095 assert(isa<TemplateTypeParmType>(NewT) &&
2096 "type parm not rewritten to type parm");
2102 auto [AssociatedDecl, Final] =
2104 std::optional<unsigned> PackIndex;
2107 "Missing argument pack");
2113 QualType Result = getSema().Context.getSubstTemplateTypeParmPackType(
2114 AssociatedDecl, T->
getIndex(), Final, Arg);
2122 PackIndex = getPackIndex(Arg);
2127 "Template argument kind mismatch");
2129 return BuildSubstTemplateTypeParmType(TLB, SuppressObjCLifetime, Final,
2140 NewTTPDecl = cast_or_null<TemplateTypeParmDecl>(
2150QualType TemplateInstantiator::TransformSubstTemplateTypeParmPackType(
2152 bool SuppressObjCLifetime) {
2161 Result = getSema().Context.getSubstTemplateTypeParmPackType(
2171 return BuildSubstTemplateTypeParmType(
2176template<
typename EntityPr
inter>
2186 ErrorLoc = PDA.first;
2190 char *MessageBuf =
new (S.
Context)
char[Message.size()];
2191 std::copy(Message.begin(), Message.end(), MessageBuf);
2193 llvm::raw_svector_ostream
OS(Entity);
2195 char *EntityBuf =
new (S.
Context)
char[Entity.size()];
2196 std::copy(Entity.begin(), Entity.end(), EntityBuf);
2198 StringRef(EntityBuf, Entity.size()), ErrorLoc,
2199 StringRef(MessageBuf, Message.size())};
2202ExprResult TemplateInstantiator::TransformRequiresTypeParams(
2216 if (getDerived().TransformFunctionTypeParams(
2217 KWLoc, Params,
nullptr,
nullptr, PTypes,
2218 &TransParams, PInfos, &ErrorIdx) ||
2219 Trap.hasErrorOccurred()) {
2225 SemaRef, Info, [&](llvm::raw_ostream &
OS) {
OS << *FailedDecl; })));
2226 return getDerived().RebuildRequiresExpr(KWLoc, Body, TransParams, TransReqs,
2238 if (AlwaysRebuild())
2239 return RebuildTypeRequirement(
2249 if (TypeInst.isInvalid())
2252 if (!TransType || Trap.hasErrorOccurred())
2254 [&] (llvm::raw_ostream&
OS) {
2257 return RebuildTypeRequirement(TransType);
2267 llvm::PointerUnion<Expr *, concepts::Requirement::SubstitutionDiagnostic *>
2276 if (ExprInst.isInvalid())
2279 if (!TransExprRes.
isInvalid() && !Trap.hasErrorOccurred() &&
2282 if (TransExprRes.
isInvalid() || Trap.hasErrorOccurred())
2287 TransExpr = TransExprRes.
get();
2290 std::optional<concepts::ExprRequirement::ReturnTypeRequirement> TransRetReq;
2292 if (RetReq.isEmpty())
2293 TransRetReq.emplace();
2294 else if (RetReq.isSubstitutionFailure())
2295 TransRetReq.emplace(RetReq.getSubstitutionDiagnostic());
2296 else if (RetReq.isTypeConstraint()) {
2298 RetReq.getTypeConstraintTemplateParameterList();
2302 if (TPLInst.isInvalid())
2307 [&] (llvm::raw_ostream&
OS) {
2308 RetReq.getTypeConstraint()->getImmediatelyDeclaredConstraint()
2313 TransRetReq.emplace(TPL);
2316 assert(TransRetReq &&
"All code paths leading here must set TransRetReq");
2317 if (
Expr *E = TransExpr.dyn_cast<
Expr *>())
2319 std::move(*TransRetReq));
2320 return RebuildExprRequirement(
2326TemplateInstantiator::TransformNestedRequirement(
2331 if (AlwaysRebuild())
2351 if (ConstrInst.isInvalid())
2355 nullptr, {Req->getConstraintExpr()},
Result, TemplateArgs,
2358 TransConstraint =
Result[0];
2359 assert(!Trap.hasErrorOccurred() &&
"Substitution failures must be handled "
2360 "by CheckConstraintSatisfaction.");
2366 if (TransConstraint.
isInvalid() || !TransConstraint.
get() ||
2369 llvm::raw_svector_ostream
OS(Entity);
2372 char *EntityBuf =
new (SemaRef.
Context)
char[Entity.size()];
2373 std::copy(Entity.begin(), Entity.end(), EntityBuf);
2375 SemaRef.
Context, StringRef(EntityBuf, Entity.size()), Satisfaction);
2378 SemaRef.
Context, TransConstraint.
get(), Satisfaction);
2416 bool AllowDeducedTST) {
2418 "Cannot perform an instantiation without some context on the "
2419 "instantiation stack");
2425 TemplateInstantiator Instantiator(*
this, Args, Loc, Entity);
2426 return AllowDeducedTST ? Instantiator.TransformTypeWithDeducedTST(T)
2427 : Instantiator.TransformType(T);
2435 "Cannot perform an instantiation without some context on the "
2436 "instantiation stack");
2450 TemplateInstantiator Instantiator(*
this, Args, Loc, Entity);
2465 "Cannot perform an instantiation without some context on the "
2466 "instantiation stack");
2473 TemplateInstantiator Instantiator(*
this, TemplateArgs, Loc, Entity);
2474 return Instantiator.TransformType(T);
2509 bool EvaluateConstraints) {
2511 "Cannot perform an instantiation without some context on the "
2512 "instantiation stack");
2517 TemplateInstantiator Instantiator(*
this, Args, Loc, Entity);
2518 Instantiator.setEvaluateConstraints(EvaluateConstraints);
2534 Result = Instantiator.TransformFunctionProtoType(
2535 TLB, Proto, ThisContext, ThisTypeQuals,
2537 bool &Changed) {
return false; });
2539 Result = Instantiator.TransformType(TLB, TL);
2553 bool Changed =
false;
2554 TemplateInstantiator Instantiator(*
this, Args, Loc,
DeclarationName());
2555 return Instantiator.TransformExceptionSpec(Loc, ESI, ExceptionStorage,
2566 ESI, ExceptionStorage, Args))
2575 struct GetContainedInventedTypeParmVisitor :
2576 public TypeVisitor<GetContainedInventedTypeParmVisitor,
2577 TemplateTypeParmDecl *> {
2578 using TypeVisitor<GetContainedInventedTypeParmVisitor,
2631 return VisitFunctionType(T);
2664 bool EvaluateConstraints) {
2668 if (!EvaluateConstraints) {
2696 int indexAdjustment, std::optional<unsigned> NumExpansions,
2697 bool ExpectParameterPack,
bool EvaluateConstraint) {
2706 NewDI =
SubstType(ExpansionTL.getPatternLoc(), TemplateArgs,
2717 }
else if (ExpectParameterPack) {
2723 diag::err_function_parameter_pack_without_parameter_packs)
2747 GetContainedInventedTypeParmVisitor().Visit(OldDI->
getType())) {
2749 auto *Inst = cast_or_null<TemplateTypeParmDecl>(
2754 if (Inst && !Inst->getTypeConstraint()) {
2824 "Cannot perform an instantiation without some context on the "
2825 "instantiation stack");
2827 TemplateInstantiator Instantiator(*
this, TemplateArgs, Loc,
2829 return Instantiator.TransformFunctionTypeParams(
2830 Loc, Params,
nullptr, ExtParamInfos, ParamTypes, OutParams, ParamInfos);
2849 Diag(Param->
getBeginLoc(), diag::err_recursive_default_argument) << FD;
2861 std::unique_ptr<LocalInstantiationScope> LIS;
2869 LIS = std::make_unique<LocalInstantiationScope>(*
this);
2872 if (addInstantiatedParametersToScope(FD, PatternFD, *LIS, TemplateArgs))
2894 Result = InitSeq.Perform(*
this, Entity, Kind, ResultE);
2927 for (
const auto &
Base : Pattern->
bases()) {
2928 if (!
Base.getType()->isDependentType()) {
2930 if (RD->isInvalidDecl())
2939 if (
Base.isPackExpansion()) {
2945 bool ShouldExpand =
false;
2946 bool RetainExpansion =
false;
2947 std::optional<unsigned> NumExpansions;
2949 Base.getSourceRange(),
2951 TemplateArgs, ShouldExpand,
2960 for (
unsigned I = 0; I != *NumExpansions; ++I) {
2965 Base.getSourceRange().getBegin(),
2974 Base.getSourceRange(),
2976 Base.getAccessSpecifierAsWritten(),
2979 InstantiatedBases.push_back(InstantiatedBase);
2988 EllipsisLoc =
Base.getEllipsisLoc();
2992 Base.getSourceRange().getBegin(),
2997 Base.getSourceRange().getBegin(),
3008 Base.getSourceRange(),
3010 Base.getAccessSpecifierAsWritten(),
3013 InstantiatedBases.push_back(InstantiatedBase);
3067 Pattern, PatternDef, TSK, Complain))
3070 llvm::TimeTraceScope TimeScope(
"InstantiateClass", [&]() {
3072 llvm::raw_string_ostream
OS(Name);
3078 Pattern = PatternDef;
3084 MSInfo->setPointOfInstantiation(PointOfInstantiation);
3086 = dyn_cast<ClassTemplateSpecializationDecl>(Instantiation)) {
3087 Spec->setTemplateSpecializationKind(TSK);
3088 Spec->setPointOfInstantiation(PointOfInstantiation);
3096 "instantiating class definition");
3114 SavePendingParsedClassStateRAII SavedPendingParsedClassState(*
this);
3140 bool MightHaveConstexprVirtualFunctions =
false;
3151 if (
Member->getDeclContext() != Pattern)
3158 if (isa<BlockDecl>(
Member) ||
3159 (isa<CXXRecordDecl>(
Member) && cast<CXXRecordDecl>(
Member)->isLambda()))
3162 if (
Member->isInvalidDecl()) {
3169 if (
FieldDecl *Field = dyn_cast<FieldDecl>(NewMember)) {
3170 Fields.push_back(Field);
3171 }
else if (
EnumDecl *
Enum = dyn_cast<EnumDecl>(NewMember)) {
3177 Enum->isCompleteDefinition()) {
3179 assert(MSInfo &&
"no spec info for member enum specialization");
3184 if (SA->isFailed()) {
3190 }
else if (
CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(NewMember)) {
3193 MightHaveConstexprVirtualFunctions =
true;
3214 if (ParsingClassDepth == 0)
3219 for (LateInstantiatedAttrVec::iterator I = LateAttrs.begin(),
3220 E = LateAttrs.end(); I != E; ++I) {
3225 auto *ND = cast<NamedDecl>(I->NewDecl);
3226 auto *ThisContext = dyn_cast_or_null<CXXRecordDecl>(ND->getDeclContext());
3228 ND->isCXXInstanceMember());
3233 I->NewDecl->addAttr(NewAttr);
3262 P->first,
P->second)) {
3275 P->first,
P->second)) {
3292 else if (MightHaveConstexprVirtualFunctions)
3324 Pattern, PatternDef, TSK,
true))
3326 Pattern = PatternDef;
3332 MSInfo->setPointOfInstantiation(PointOfInstantiation);
3341 "instantiating enum definition");
3391 "pattern and instantiation disagree about init style");
3399 Diag(PointOfInstantiation,
3400 diag::err_default_member_initializer_not_yet_parsed)
3401 << OutermostClass << Pattern;
3402 Diag(Pattern->getEndLoc(),
3403 diag::note_default_member_initializer_not_yet_parsed);
3413 Diag(PointOfInstantiation, diag::err_default_member_initializer_cycle)
3418 "instantiating default member init");
3426 PointOfInstantiation, Instantiation,
CurContext};
3437 assert((!Init || !isa<ParenListExpr>(Init)) &&
"call-style init in class");
3439 Instantiation, Init ? Init->getBeginLoc() :
SourceLocation(), Init);
3442 L->DefaultMemberInitializerInstantiated(Instantiation);
3451 struct PartialSpecMatchResult {
3466 for (
unsigned I = 0, N = PartialSpecs.size(); I != N; ++I) {
3510 for (
unsigned I = 0, N = PartialSpecs.size(); I != N; ++I) {
3522 Matched.push_back(PartialSpecMatchResult());
3523 Matched.back().Partial = Partial;
3532 if (Matched.size() >= 1) {
3534 if (Matched.size() == 1) {
3547 PEnd = Matched.end();
3550 P->Partial, Best->Partial, PointOfInstantiation) ==
3557 bool Ambiguous =
false;
3559 PEnd = Matched.end();
3562 P->Partial, Best->Partial,
3563 PointOfInstantiation) != Best->Partial) {
3573 S.
Diag(PointOfInstantiation,
3574 diag::err_partial_spec_ordering_ambiguous)
3575 << ClassTemplateSpec;
3579 PEnd = Matched.end();
3581 S.
Diag(
P->Partial->getLocation(), diag::note_partial_spec_match)
3583 P->Partial->getTemplateParameters(), *
P->Args);
3598 if (
auto *PartialSpec =
3601 while (PartialSpec->getInstantiatedFromMember()) {
3604 if (PartialSpec->isMemberSpecialization())
3607 PartialSpec = PartialSpec->getInstantiatedFromMember();
3609 Pattern = PartialSpec;
3631 ClassTemplateSpec = cast<ClassTemplateSpecializationDecl>(
3638 ClassTemplateSpec, TSK);
3643 PointOfInstantiation, ClassTemplateSpec, Pattern.
get(),
3662 "Unexpected template specialization kind!");
3663 for (
auto *D : Instantiation->
decls()) {
3664 bool SuppressNew =
false;
3665 if (
auto *Function = dyn_cast<FunctionDecl>(D)) {
3667 Function->getInstantiatedFromMemberFunction()) {
3669 if (Function->isIneligibleOrNotSelected())
3672 if (Function->getTrailingRequiresClause()) {
3680 if (Function->hasAttr<ExcludeFromExplicitInstantiationAttr>())
3684 Function->getMemberSpecializationInfo();
3685 assert(MSInfo &&
"No member specialization information?");
3707 Function->setTemplateSpecializationKind(TSK, PointOfInstantiation);
3709 if (Function->isDefined()) {
3717 std::make_pair(Function, PointOfInstantiation));
3720 }
else if (
auto *Var = dyn_cast<VarDecl>(D)) {
3721 if (isa<VarTemplateSpecializationDecl>(Var))
3725 if (Var->
hasAttr<ExcludeFromExplicitInstantiationAttr>())
3729 assert(MSInfo &&
"No member specialization information?");
3758 }
else if (
auto *Record = dyn_cast<CXXRecordDecl>(D)) {
3759 if (Record->hasAttr<ExcludeFromExplicitInstantiationAttr>())
3767 if (Record->isInjectedClassName() || Record->getPreviousDecl() ||
3772 assert(MSInfo &&
"No member specialization information?");
3797 CXXRecordDecl *Pattern = Record->getInstantiatedFromMemberClass();
3798 assert(Pattern &&
"Missing instantiated-from-template information");
3800 if (!Record->getDefinition()) {
3821 Record->getTemplateSpecializationKind() ==
3823 Record->setTemplateSpecializationKind(TSK);
3828 Pattern = cast_or_null<CXXRecordDecl>(Record->getDefinition());
3832 }
else if (
auto *
Enum = dyn_cast<EnumDecl>(D)) {
3834 assert(MSInfo &&
"No member specialization information?");
3841 PointOfInstantiation, TSK,
Enum,
3847 if (
Enum->getDefinition())
3850 EnumDecl *Pattern =
Enum->getTemplateInstantiationPattern();
3851 assert(Pattern &&
"Missing instantiated-from-template information");
3862 }
else if (
auto *Field = dyn_cast<FieldDecl>(D)) {
3869 ClassPattern->
lookup(Field->getDeclName());
3905 TemplateInstantiator Instantiator(*
this, TemplateArgs,
3908 return Instantiator.TransformStmt(S);
3915 TemplateInstantiator Instantiator(*
this, TemplateArgs,
SourceLocation(),
3917 return Instantiator.TransformTemplateArguments(Args.begin(), Args.end(), Out);
3925 TemplateInstantiator Instantiator(*
this, TemplateArgs,
3928 return Instantiator.TransformExpr(E);
3939 TemplateInstantiator Instantiator(*
this, TemplateArgs,
SourceLocation(),
3941 return Instantiator.TransformExpr(E);
3946 bool CXXDirectInit) {
3947 TemplateInstantiator Instantiator(*
this, TemplateArgs,
SourceLocation(),
3949 return Instantiator.TransformInitializer(Init, CXXDirectInit);
3958 TemplateInstantiator Instantiator(*
this, TemplateArgs,
3961 return Instantiator.TransformExprs(Exprs.data(), Exprs.size(),
3971 TemplateInstantiator Instantiator(*
this, TemplateArgs, NNS.
getBeginLoc(),
3973 return Instantiator.TransformNestedNameSpecifierLoc(NNS);
3980 TemplateInstantiator Instantiator(*
this, TemplateArgs, NameInfo.
getLoc(),
3982 return Instantiator.TransformDeclarationNameInfo(NameInfo);
3989 TemplateInstantiator Instantiator(*
this, TemplateArgs, Loc,
3992 SS.
Adopt(QualifierLoc);
3993 return Instantiator.TransformTemplateName(SS, Name, Loc);
4001 if (
const ParmVarDecl *PV = dyn_cast<ParmVarDecl>(D)) {
4002 if (
const FunctionDecl *FD = dyn_cast<FunctionDecl>(PV->getDeclContext())) {
4003 unsigned i = PV->getFunctionScopeIndex();
4006 if (i < FD->getNumParams() && FD->getParamDecl(i) == PV)
4014llvm::PointerUnion<Decl *, LocalInstantiationScope::DeclArgumentPack *> *
4018 Current = Current->Outer) {
4021 const Decl *CheckD = D;
4023 LocalDeclsMap::iterator Found = Current->LocalDecls.find(CheckD);
4024 if (Found != Current->LocalDecls.end())
4025 return &Found->second;
4029 if (
const TagDecl *Tag = dyn_cast<TagDecl>(CheckD))
4036 if (!Current->CombineWithOuterScope)
4042 if (isa<NonTypeTemplateParmDecl>(D) || isa<TemplateTypeParmDecl>(D) ||
4043 isa<TemplateTemplateParmDecl>(D))
4048 if (RD->isLocalClass())
4053 if (isa<EnumDecl>(D))
4058 if (isa<TypedefNameDecl>(D) &&
4065 assert(isa<LabelDecl>(D) &&
"declaration not instantiated in this scope");
4071 llvm::PointerUnion<Decl *, DeclArgumentPack *> &Stored = LocalDecls[D];
4072 if (Stored.isNull()) {
4076 while (Current->CombineWithOuterScope && Current->Outer) {
4077 Current = Current->Outer;
4078 assert(Current->LocalDecls.find(D) == Current->LocalDecls.end() &&
4079 "Instantiated local in inner and outer scopes");
4084 Pack->push_back(cast<VarDecl>(Inst));
4086 assert(Stored.get<
Decl *>() == Inst &&
"Already instantiated this local");
4094 Pack->push_back(Inst);
4101 Current && Current->CombineWithOuterScope; Current = Current->Outer)
4102 assert(Current->LocalDecls.find(D) == Current->LocalDecls.end() &&
4103 "Creating local pack after instantiation of local");
4107 llvm::PointerUnion<Decl *, DeclArgumentPack *> &Stored = LocalDecls[D];
4110 ArgumentPacks.push_back(Pack);
4115 if (llvm::is_contained(*Pack, D))
4122 unsigned NumExplicitArgs) {
4123 assert((!PartiallySubstitutedPack || PartiallySubstitutedPack == Pack) &&
4124 "Already have a partially-substituted pack");
4125 assert((!PartiallySubstitutedPack
4126 || NumArgsInPartiallySubstitutedPack == NumExplicitArgs) &&
4127 "Wrong number of arguments in partially-substituted pack");
4128 PartiallySubstitutedPack = Pack;
4129 ArgsInPartiallySubstitutedPack = ExplicitArgs;
4130 NumArgsInPartiallySubstitutedPack = NumExplicitArgs;
4135 unsigned *NumExplicitArgs)
const {
4137 *ExplicitArgs =
nullptr;
4138 if (NumExplicitArgs)
4139 *NumExplicitArgs = 0;
4142 Current = Current->Outer) {
4143 if (Current->PartiallySubstitutedPack) {
4145 *ExplicitArgs = Current->ArgsInPartiallySubstitutedPack;
4146 if (NumExplicitArgs)
4147 *NumExplicitArgs = Current->NumArgsInPartiallySubstitutedPack;
4149 return Current->PartiallySubstitutedPack;
4152 if (!Current->CombineWithOuterScope)
This file provides AST data structures related to concepts.
Defines the clang::ASTContext interface.
This file provides some common utility functions for processing Lambda related AST Constructs.
Defines the C++ template declaration subclasses.
Defines Expressions and AST nodes for C++2a concepts.
static void print(llvm::raw_ostream &OS, const T &V, ASTContext &, QualType)
Defines the clang::LangOptions interface.
MatchFinder::MatchResult MatchResult
static const Decl * getCanonicalParmVarDecl(const Decl *D)
static concepts::Requirement::SubstitutionDiagnostic * createSubstDiag(Sema &S, TemplateDeductionInfo &Info, EntityPrinter Printer)
static bool NeedsInstantiationAsFunctionType(TypeSourceInfo *T)
static ActionResult< CXXRecordDecl * > getPatternForClassTemplateSpecialization(Sema &S, SourceLocation PointOfInstantiation, ClassTemplateSpecializationDecl *ClassTemplateSpec, TemplateSpecializationKind TSK)
Get the instantiation pattern to use to instantiate the definition of a given ClassTemplateSpecializa...
static std::string convertCallArgsToString(Sema &S, llvm::ArrayRef< const Expr * > Args)
static TemplateArgument getPackSubstitutedTemplateArgument(Sema &S, TemplateArgument Arg)
Defines utilities for dealing with stack allocation and stack space.
C Language Family Type Representation.
virtual void HandleTagDeclDefinition(TagDecl *D)
HandleTagDeclDefinition - This callback is invoked each time a TagDecl (e.g.
virtual bool HandleTopLevelDecl(DeclGroupRef D)
HandleTopLevelDecl - Handle the specified top-level declaration.
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
TranslationUnitDecl * getTranslationUnitDecl() const
QualType getTagDeclType(const TagDecl *Decl) const
Return the unique reference to the type for the specified TagDecl (struct/union/class/enum) decl.
bool hasSameType(QualType T1, QualType T2) const
Determine whether the given types T1 and T2 are equivalent.
QualType getTypeDeclType(const TypeDecl *Decl, const TypeDecl *PrevDecl=nullptr) const
Return the unique reference to the type for the specified type declaration.
QualType getQualifiedType(SplitQualType split) const
Un-split a SplitQualType.
const clang::PrintingPolicy & getPrintingPolicy() const
const TargetInfo & getTargetInfo() const
Represents a type which was implicitly adjusted by the semantic engine for arbitrary reasons.
QualType getOriginalType() const
Represents an array type, per C99 6.7.5.2 - Array Declarators.
QualType getElementType() const
Attr - This represents one attribute.
An attributed type is a type to which a type attribute has been applied.
QualType getModifiedType() const
QualType getPointeeType() const
Represents a base class of a C++ class.
A default argument (C++ [dcl.fct.default]).
SourceLocation getUsedLocation() const
Retrieve the location where this default argument was actually used.
const ParmVarDecl * getParam() const
Represents a static or instance method of a struct/union/class.
Represents a C++ struct/union/class.
Decl * getLambdaContextDecl() const
Retrieve the declaration that provides additional context for a lambda, when the normal declaration c...
const FunctionDecl * isLocalClass() const
If the class is a local class [class.local], returns the enclosing function declaration.
CXXRecordDecl * getInstantiatedFromMemberClass() const
If this record is an instantiation of a member class, retrieves the member class from which it was in...
bool isLambda() const
Determine whether this class describes a lambda function object.
CXXRecordDecl * getDefinition() const
unsigned getNumBases() const
Retrieves the number of base classes of this class.
const CXXRecordDecl * getTemplateInstantiationPattern() const
Retrieve the record declaration from which this record could be instantiated.
TemplateSpecializationKind getTemplateSpecializationKind() const
Determine whether this particular class is a specialization or instantiation of a class template or m...
ClassTemplateDecl * getDescribedClassTemplate() const
Retrieves the class template that is described by this class declaration.
MemberSpecializationInfo * getMemberSpecializationInfo() const
If this class is an instantiation of a member class of a class template specialization,...
CXXRecordDecl * getCanonicalDecl() override
Retrieves the "canonical" declaration of the given declaration.
void setTemplateSpecializationKind(TemplateSpecializationKind TSK)
Set the kind of specialization or template instantiation this is.
Represents a C++ nested-name-specifier or a global scope specifier.
void Adopt(NestedNameSpecifierLoc Other)
Adopt an existing nested-name-specifier (with source-range information).
Declaration of a class template.
CXXRecordDecl * getTemplatedDecl() const
Get the underlying class declarations of the template.
llvm::FoldingSetVector< ClassTemplatePartialSpecializationDecl > & getPartialSpecializations() const
Retrieve the set of partial specializations of this class template.
ClassTemplateDecl * getInstantiatedFromMemberTemplate() const
Represents a class template specialization, which refers to a class template with a given set of temp...
TemplateSpecializationKind getSpecializationKind() const
Determine the kind of specialization that this declaration represents.
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)?...
llvm::PointerUnion< ClassTemplateDecl *, ClassTemplatePartialSpecializationDecl * > getSpecializedTemplateOrPartial() const
Retrieve the class template or class template partial specialization which was specialized by this.
const TemplateArgumentList & getTemplateArgs() const
Retrieve the template arguments of the class template specialization.
const TemplateArgumentList & getTemplateInstantiationArgs() const
Retrieve the set of template arguments that should be used to instantiate members of the class templa...
void setInstantiationOf(ClassTemplatePartialSpecializationDecl *PartialSpec, const TemplateArgumentList *TemplateArgs)
Note that this class template specialization is actually an instantiation of the given class template...
const NestedNameSpecifierLoc & getNestedNameSpecifierLoc() const
const DeclarationNameInfo & getConceptNameInfo() const
ConceptDecl * getNamedConcept() const
const ASTTemplateArgumentListInfo * getTemplateArgsAsWritten() const
The result of a constraint satisfaction check, containing the necessary information to diagnose an un...
bool HasSubstitutionFailure()
static DeclAccessPair make(NamedDecl *D, AccessSpecifier AS)
The results of name lookup within a DeclContext.
DeclContext - This is used only as base class of specific decl types that can act as declaration cont...
bool isFileContext() const
bool isDependentContext() const
Determines whether this context is dependent on a template parameter.
lookup_result lookup(DeclarationName Name) const
lookup - Find the declarations (if any) with the given Name in this context.
bool isTranslationUnit() const
RecordDecl * getOuterLexicalRecordContext()
Retrieve the outermost lexically enclosing record context.
decl_range decls() const
decls_begin/decls_end - Iterate over the declarations stored in this context.
A reference to a declared variable, function, enum, etc.
SourceLocation getLocation() const
Decl - This represents one declaration (or definition), e.g.
Decl * getPreviousDecl()
Retrieve the previous declaration that declares the same entity as this declaration,...
FriendObjectKind getFriendObjectKind() const
Determines whether this declaration is the object of a friend declaration and, if so,...
bool isImplicit() const
isImplicit - Indicates whether the declaration was implicitly generated by the implementation.
bool isParameterPack() const
Whether this declaration is a parameter pack.
void setInvalidDecl(bool Invalid=true)
setInvalidDecl - Indicates the Decl had a semantic error.
bool isFileContextDecl() const
static Decl * castFromDeclContext(const DeclContext *)
DeclContext * getNonTransparentDeclContext()
Return the non transparent context.
bool isInvalidDecl() const
SourceLocation getLocation() const
void setLocation(SourceLocation L)
bool isDefinedOutsideFunctionOrMethod() const
isDefinedOutsideFunctionOrMethod - This predicate returns true if this scoped decl is defined outside...
DeclContext * getDeclContext()
void setDeclContext(DeclContext *DC)
setDeclContext - Set both the semantic and lexical DeclContext to DC.
DeclContext * getLexicalDeclContext()
getLexicalDeclContext - The declaration context where this Decl was lexically declared (LexicalDC).
virtual Decl * getCanonicalDecl()
Retrieves the "canonical" declaration of the given declaration.
void setVisibleDespiteOwningModule()
Set that this declaration is globally visible, even if it came from a module that is not visible.
The name of a declaration.
SourceLocation getInnerLocStart() const
Return start of source range ignoring outer template declarations.
SourceLocation getOuterLocStart() const
Return start of source range taking into account any outer template declarations.
SourceLocation getBeginLoc() const LLVM_READONLY
TypeSourceInfo * getTypeSourceInfo() const
Information about one declarator, including the parsed type information and the identifier.
Represents an extended vector type where either the type or size is dependent.
QualType getElementType() const
DiagnosticBuilder Report(SourceLocation Loc, unsigned DiagID)
Issue the message to the client.
bool hasFatalErrorOccurred() const
unsigned getTemplateBacktraceLimit() const
Retrieve the maximum number of template instantiation notes to emit along with a given diagnostic.
Represents a type that was referred to using an elaborated type keyword, e.g., struct S,...
QualType getNamedType() const
Retrieve the type named by the qualified-id.
RAII object that enters a new expression evaluation context.
MemberSpecializationInfo * getMemberSpecializationInfo() const
If this enumeration is an instantiation of a member enumeration of a class template specialization,...
void setTemplateSpecializationKind(TemplateSpecializationKind TSK, SourceLocation PointOfInstantiation=SourceLocation())
For an enumeration member that was instantiated from a member enumeration of a templated class,...
EnumDecl * getInstantiatedFromMemberEnum() const
Returns the enumeration (declared within the template) from which this enumeration type was instantia...
EnumDecl * getDefinition() const
This represents one expression.
ExprValueKind getValueKind() const
getValueKind - The value kind that this expression produces.
bool isTypeDependent() const
Determines whether the type of this expression depends on.
bool isLValue() const
isLValue - True if this expression is an "l-value" according to the rules of the current language.
bool isInstantiationDependent() const
Whether this expression is instantiation-dependent, meaning that it depends in some way on.
SourceLocation getExprLoc() const LLVM_READONLY
getExprLoc - Return the preferred location for the arrow when diagnosing a problem with a generic exp...
bool hasPlaceholderType() const
Returns whether this expression has a placeholder type.
Represents a member of a struct/union/class.
bool hasInClassInitializer() const
Determine whether this member has a C++11 default member initializer.
InClassInitStyle getInClassInitStyle() const
Get the kind of (C++11) default member initializer that this field has.
Expr * getInClassInitializer() const
Get the C++11 default member initializer for this member, or null if one has not been set.
const RecordDecl * getParent() const
Returns the parent of this field declaration, which is the struct in which this field is defined.
static FixItHint CreateReplacement(CharSourceRange RemoveRange, StringRef Code)
Create a code modification hint that replaces the given source range with the given code string.
Represents a function declaration or definition.
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...
bool isConstexpr() const
Whether this is a (C++11) constexpr function or constexpr constructor.
bool isVirtualAsWritten() const
Whether this function is marked as virtual explicitly.
Represents a reference to a function parameter pack or init-capture pack that has been substituted bu...
VarDecl * getParameterPack() const
Get the parameter pack which this expression refers to.
VarDecl * getExpansion(unsigned I) const
Get an expansion of the parameter pack by index.
VarDecl *const * iterator
Iterators over the parameters which the parameter pack expanded into.
unsigned getNumExpansions() const
Get the number of parameters in this parameter pack.
SourceLocation getParameterPackLocation() const
Get the location of the parameter pack.
static FunctionParmPackExpr * Create(const ASTContext &Context, QualType T, VarDecl *ParamPack, SourceLocation NameLoc, ArrayRef< VarDecl * > Params)
Represents a prototype with parameter type info, e.g.
ExtProtoInfo getExtProtoInfo() const
Declaration of a template function.
ArrayRef< ParmVarDecl * > getParams() const
Interesting information about a specific parameter that can't simply be reflected in parameter's type...
FunctionType - C99 6.7.5.3 - Function Declarators.
QualType getReturnType() const
One of these records is kept for each identifier that is lexed.
ArrayRef< TemplateArgument > getTemplateArguments() const
const TypeClass * getTypePtr() const
Describes the kind of initialization being performed, along with location information for tokens rela...
static InitializationKind CreateCopy(SourceLocation InitLoc, SourceLocation EqualLoc, bool AllowExplicitConvs=false)
Create a copy initialization.
Describes the sequence of initializations required to initialize a given object or reference with a s...
Describes an entity that is being initialized.
static InitializedEntity InitializeParameter(ASTContext &Context, ParmVarDecl *Parm)
Create the initialization entity for a parameter.
A C++ lambda expression, which produces a function object (of unspecified type) that can be invoked l...
A stack-allocated class that identifies which local variable declaration instantiations are present i...
void SetPartiallySubstitutedPack(NamedDecl *Pack, const TemplateArgument *ExplicitArgs, unsigned NumExplicitArgs)
Note that the given parameter pack has been partially substituted via explicit specification of templ...
NamedDecl * getPartiallySubstitutedPack(const TemplateArgument **ExplicitArgs=nullptr, unsigned *NumExplicitArgs=nullptr) const
Retrieve the partially-substitued template parameter pack.
bool isLocalPackExpansion(const Decl *D)
Determine whether D is a pack expansion created in this scope.
static void deleteScopes(LocalInstantiationScope *Scope, LocalInstantiationScope *Outermost)
deletes the given scope, and all outer scopes, down to the given outermost scope.
void InstantiatedLocal(const Decl *D, Decl *Inst)
void InstantiatedLocalPackArg(const Decl *D, VarDecl *Inst)
void MakeInstantiatedLocalArgPack(const Decl *D)
llvm::PointerUnion< Decl *, DeclArgumentPack * > * findInstantiationOf(const Decl *D)
Find the instantiation of the declaration D within the current instantiation scope.
Sugar type that represents a type that was qualified by a qualifier written as a macro invocation.
QualType getUnderlyingType() const
A pointer to member type per C++ 8.3.3 - Pointers to members.
QualType getPointeeType() const
Provides information a specialization of a member of a class template, which may be a member function...
void setTemplateSpecializationKind(TemplateSpecializationKind TSK)
Set the template specialization kind.
TemplateSpecializationKind getTemplateSpecializationKind() const
Determine what kind of template specialization this is.
SourceLocation getPointOfInstantiation() const
Retrieve the first point of instantiation of this member.
void setPointOfInstantiation(SourceLocation POI)
Set the first point of instantiation.
Describes a module or submodule.
Data structure that captures multiple levels of template argument lists for use in template instantia...
bool hasTemplateArgument(unsigned Depth, unsigned Index) const
Determine whether there is a non-NULL template argument at the given depth and index.
const ArgList & getInnermost() const
Retrieve the innermost template argument list.
std::pair< Decl *, bool > getAssociatedDecl(unsigned Depth) const
A template-like entity which owns the whole pattern being substituted.
unsigned getNumLevels() const
Determine the number of levels in this template argument list.
unsigned getNumSubstitutedLevels() const
Determine the number of substituted levels in this template argument list.
unsigned getNewDepth(unsigned OldDepth) const
Determine how many of the OldDepth outermost template parameter lists would be removed by substitutin...
void setArgument(unsigned Depth, unsigned Index, TemplateArgument Arg)
Clear out a specific template argument.
bool isRewrite() const
Determine whether we are rewriting template parameters rather than substituting for them.
This represents a decl that may have a name.
IdentifierInfo * getIdentifier() const
Get the identifier that names this declaration, if there is one.
StringRef getName() const
Get the name of identifier for this declaration as a StringRef.
DeclarationName getDeclName() const
Get the actual, stored name of the declaration, which may be a special name.
virtual void getNameForDiagnostic(raw_ostream &OS, const PrintingPolicy &Policy, bool Qualified) const
Appends a human-readable name for this declaration into the given stream.
virtual void printName(raw_ostream &OS, const PrintingPolicy &Policy) const
Pretty-print the unqualified name of this declaration.
A C++ nested-name-specifier augmented with source location information.
SourceLocation getBeginLoc() const
Retrieve the location of the beginning of this nested-name-specifier.
NonTypeTemplateParmDecl - Declares a non-type template parameter, e.g., "Size" in.
QualType getExpansionType(unsigned I) const
Retrieve a particular expansion type within an expanded parameter pack.
unsigned getPosition() const
Get the position of the template parameter within its parameter list.
bool isExpandedParameterPack() const
Whether this parameter is a non-type template parameter pack that has a known list of different types...
bool isParameterPack() const
Whether this parameter is a non-type template parameter pack.
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 pack expansion of types.
QualType getPattern() const
Retrieve the pattern of this pack expansion, which is the type that will be repeatedly instantiated w...
Sugar for parentheses used when specifying types.
QualType getInnerType() const
Represents a parameter to a function.
unsigned getFunctionScopeIndex() const
Returns the index of this parameter in its prototype or method scope.
void setDefaultArg(Expr *defarg)
void setUnparsedDefaultArg()
Specify that this parameter has an unparsed default argument.
bool hasUnparsedDefaultArg() const
Determines whether this parameter has a default argument that has not yet been parsed.
void setUninstantiatedDefaultArg(Expr *arg)
void setScopeInfo(unsigned scopeDepth, unsigned parameterIndex)
bool hasUninstantiatedDefaultArg() const
bool hasInheritedDefaultArg() const
Expr * getUninstantiatedDefaultArg()
unsigned getFunctionScopeDepth() const
void setHasInheritedDefaultArg(bool I=true)
PointerType - C99 6.7.5.1 - Pointer Declarators.
QualType getPointeeType() const
[C99 6.4.2.2] - A predefined identifier such as func.
SourceLocation getLocation() const
IdentKind getIdentKind() const
PrettyDeclStackTraceEntry - If a crash occurs in the parser while parsing something related to a decl...
A (possibly-)qualified type.
QualType getNonLValueExprType(const ASTContext &Context) const
Determine the type of a (typically non-lvalue) expression with the specified result type.
void addConst()
Add the const type qualifier to this QualType.
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.
Qualifiers getQualifiers() const
Retrieve the set of qualifiers applied to this type.
QualType getUnqualifiedType() const
Retrieve the unqualified variant of the given type, removing as little sugar as possible.
The collection of all-type qualifiers we support.
void removeObjCLifetime()
Represents a struct/union/class.
A helper class that allows the use of isa/cast/dyncast to detect TagType objects of structs/unions/cl...
bool isMemberSpecialization() const
Determines whether this template was a specialization of a member template.
Base for LValueReferenceType and RValueReferenceType.
QualType getPointeeTypeAsWritten() const
Represents the body of a requires-expression.
C++2a [expr.prim.req]: A requires-expression provides a concise way to express requirements on templa...
RequiresExprBodyDecl * getBody() const
Scope - A scope is a transient data structure that is used while parsing the program.
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...
For a defaulted function, the kind of defaulted function that it is.
DefaultedComparisonKind asComparison() const
bool isSpecialMember() const
CXXSpecialMember asSpecialMember() const
bool isComparison() const
A helper class for building up ExtParameterInfos.
RAII class used to determine whether SFINAE has trapped any errors that occur during template argumen...
Sema - This implements semantic analysis and AST building for C.
bool SubstTypeConstraint(TemplateTypeParmDecl *Inst, const TypeConstraint *TC, const MultiLevelTemplateArgumentList &TemplateArgs, bool EvaluateConstraint)
SmallVector< CodeSynthesisContext, 16 > CodeSynthesisContexts
List of active code synthesis contexts.
LocalInstantiationScope * CurrentInstantiationScope
The current instantiation scope used to store local variables.
DefaultedFunctionKind getDefaultedFunctionKind(const FunctionDecl *FD)
Determine the kind of defaulting that would be done for a given function.
bool CheckParameterPacksForExpansion(SourceLocation EllipsisLoc, SourceRange PatternRange, ArrayRef< UnexpandedParameterPack > Unexpanded, const MultiLevelTemplateArgumentList &TemplateArgs, bool &ShouldExpand, bool &RetainExpansion, std::optional< unsigned > &NumExpansions)
Determine whether we could expand a pack expansion with the given set of parameter packs into separat...
TemplateName SubstTemplateName(NestedNameSpecifierLoc QualifierLoc, TemplateName Name, SourceLocation Loc, const MultiLevelTemplateArgumentList &TemplateArgs)
ParmVarDecl * SubstParmVarDecl(ParmVarDecl *D, const MultiLevelTemplateArgumentList &TemplateArgs, int indexAdjustment, std::optional< unsigned > NumExpansions, bool ExpectParameterPack, bool EvaluateConstraints=true)
void ActOnFinishCXXNonNestedClass()
NamedDecl * FindInstantiatedDecl(SourceLocation Loc, NamedDecl *D, const MultiLevelTemplateArgumentList &TemplateArgs, bool FindingInstantiatedContext=false)
Find the instantiation of the given declaration within the current instantiation.
llvm::DenseSet< Module * > LookupModulesCache
Cache of additional modules that should be used for name lookup within the current template instantia...
SemaDiagnosticBuilder Diag(SourceLocation Loc, unsigned DiagID, bool DeferHint=false)
Emit a diagnostic.
void ActOnFinishDelayedMemberInitializers(Decl *Record)
MultiLevelTemplateArgumentList getTemplateInstantiationArgs(const NamedDecl *D, bool Final=false, const TemplateArgumentList *Innermost=nullptr, bool RelativeToPrimary=false, const FunctionDecl *Pattern=nullptr, bool ForConstraintInstantiation=false, bool SkipForSpecialization=false)
Retrieve the template argument list(s) that should be used to instantiate the definition of the given...
bool DiagnoseUninstantiableTemplate(SourceLocation PointOfInstantiation, NamedDecl *Instantiation, bool InstantiatedFromMember, const NamedDecl *Pattern, const NamedDecl *PatternDef, TemplateSpecializationKind TSK, bool Complain=true)
Determine whether we would be unable to instantiate this template (because it either has no definitio...
void InstantiateClassTemplateSpecializationMembers(SourceLocation PointOfInstantiation, ClassTemplateSpecializationDecl *ClassTemplateSpec, TemplateSpecializationKind TSK)
Instantiate the definitions of all of the members of the given class template specialization,...
ClassTemplatePartialSpecializationDecl * getMoreSpecializedPartialSpecialization(ClassTemplatePartialSpecializationDecl *PS1, ClassTemplatePartialSpecializationDecl *PS2, SourceLocation Loc)
Returns the more specialized class template partial specialization according to the rules of partial ...
llvm::DenseSet< std::pair< Decl *, unsigned > > InstantiatingSpecializations
Specializations whose definitions are currently being instantiated.
void deduceOpenCLAddressSpace(ValueDecl *decl)
bool AttachTypeConstraint(NestedNameSpecifierLoc NS, DeclarationNameInfo NameInfo, ConceptDecl *NamedConcept, const TemplateArgumentListInfo *TemplateArgs, TemplateTypeParmDecl *ConstrainedParameter, SourceLocation EllipsisLoc)
Attach a type-constraint to a template parameter.
ExprResult SubstInitializer(Expr *E, const MultiLevelTemplateArgumentList &TemplateArgs, bool CXXDirectInit)
void SubstExceptionSpec(FunctionDecl *New, const FunctionProtoType *Proto, const MultiLevelTemplateArgumentList &Args)
@ CTAK_Specified
The template argument was specified in the code or was instantiated with some deduced template argume...
bool SubstExprs(ArrayRef< Expr * > Exprs, bool IsCall, const MultiLevelTemplateArgumentList &TemplateArgs, SmallVectorImpl< Expr * > &Outputs)
Substitute the given template arguments into a list of expressions, expanding pack expansions if requ...
StmtResult SubstStmt(Stmt *S, const MultiLevelTemplateArgumentList &TemplateArgs)
bool InNonInstantiationSFINAEContext
Whether we are in a SFINAE context that is not associated with template instantiation.
ExprResult SubstExpr(Expr *E, const MultiLevelTemplateArgumentList &TemplateArgs)
DiagnosticsEngine & getDiagnostics() const
TypeSourceInfo * CheckPackExpansion(TypeSourceInfo *Pattern, SourceLocation EllipsisLoc, std::optional< unsigned > NumExpansions)
Construct a pack expansion type from the pattern of the pack expansion.
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.
void InstantiateVariableDefinition(SourceLocation PointOfInstantiation, VarDecl *Var, bool Recursive=false, bool DefinitionRequired=false, bool AtEndOfTU=false)
Instantiate the definition of the given variable from its template.
void ActOnStartCXXInClassMemberInitializer()
Enter a new C++ default initializer scope.
PrintingPolicy getPrintingPolicy() const
Retrieve a suitable printing policy for diagnostics.
bool SubstTemplateArguments(ArrayRef< TemplateArgumentLoc > Args, const MultiLevelTemplateArgumentList &TemplateArgs, TemplateArgumentListInfo &Outputs)
bool isAcceptableTagRedeclaration(const TagDecl *Previous, TagTypeKind NewTag, bool isDefinition, SourceLocation NewTagLoc, const IdentifierInfo *Name)
Determine whether a tag with a given kind is acceptable as a redeclaration of the given tag declarati...
bool InstantiateClassTemplateSpecialization(SourceLocation PointOfInstantiation, ClassTemplateSpecializationDecl *ClassTemplateSpec, TemplateSpecializationKind TSK, bool Complain=true)
void InstantiateAttrs(const MultiLevelTemplateArgumentList &TemplateArgs, const Decl *Pattern, Decl *Inst, LateInstantiatedAttrVec *LateAttrs=nullptr, LocalInstantiationScope *OuterMostScope=nullptr)
const LangOptions & getLangOpts() const
TemplateDeductionResult DeduceTemplateArguments(ClassTemplatePartialSpecializationDecl *Partial, const TemplateArgumentList &TemplateArgs, sema::TemplateDeductionInfo &Info)
Perform template argument deduction to determine whether the given template arguments match the given...
bool CheckSpecializationInstantiationRedecl(SourceLocation NewLoc, TemplateSpecializationKind NewTSK, NamedDecl *PrevDecl, TemplateSpecializationKind PrevTSK, SourceLocation PrevPtOfInstantiation, bool &SuppressNew)
Diagnose cases where we have an explicit template specialization before/after an explicit template in...
void collectUnexpandedParameterPacks(TemplateArgument Arg, SmallVectorImpl< UnexpandedParameterPack > &Unexpanded)
Collect the set of unexpanded parameter packs within the given template argument.
ExprResult BuildExpressionFromIntegralTemplateArgument(const TemplateArgument &Arg, SourceLocation Loc)
Construct a new expression that refers to the given integral template argument with the given source-...
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...
void InstantiateClassMembers(SourceLocation PointOfInstantiation, CXXRecordDecl *Instantiation, const MultiLevelTemplateArgumentList &TemplateArgs, TemplateSpecializationKind TSK)
Instantiates the definitions of all of the member of the given class, which is an instantiation of a ...
TemplateDeductionResult
Describes the result of template argument deduction.
void MarkVirtualMembersReferenced(SourceLocation Loc, const CXXRecordDecl *RD, bool ConstexprOnly=false)
MarkVirtualMembersReferenced - Will mark all members of the given CXXRecordDecl referenced.
ParmVarDecl * CheckParameter(DeclContext *DC, SourceLocation StartLoc, SourceLocation NameLoc, IdentifierInfo *Name, QualType T, TypeSourceInfo *TSInfo, StorageClass SC)
DeclarationNameInfo SubstDeclarationNameInfo(const DeclarationNameInfo &NameInfo, const MultiLevelTemplateArgumentList &TemplateArgs)
Do template substitution on declaration name info.
void MarkVTableUsed(SourceLocation Loc, CXXRecordDecl *Class, bool DefinitionRequired=false)
Note that the vtable for the given class was used at the given location.
std::vector< std::unique_ptr< TemplateInstantiationCallback > > TemplateInstCallbacks
The template instantiation callbacks to trace or track instantiations (objects can be chained).
void PrintInstantiationStack()
Prints the current instantiation stack through a series of notes.
void popCodeSynthesisContext()
bool usesPartialOrExplicitSpecialization(SourceLocation Loc, ClassTemplateSpecializationDecl *ClassTemplateSpec)
void pushCodeSynthesisContext(CodeSynthesisContext Ctx)
std::optional< sema::TemplateDeductionInfo * > isSFINAEContext() const
Determines whether we are currently in a context where template argument substitution failures are no...
CXXBaseSpecifier * CheckBaseSpecifier(CXXRecordDecl *Class, SourceRange SpecifierRange, bool Virtual, AccessSpecifier Access, TypeSourceInfo *TInfo, SourceLocation EllipsisLoc)
ActOnBaseSpecifier - Parsed a base specifier.
UnparsedDefaultArgInstantiationsMap UnparsedDefaultArgInstantiations
A mapping from parameters with unparsed default arguments to the set of instantiations of each parame...
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...
int ArgumentPackSubstitutionIndex
The current index into pack expansion arguments that will be used for substitution of parameter packs...
DeclContext * CurContext
CurContext - This is the current declaration context of parsing.
std::deque< PendingImplicitInstantiation > PendingLocalImplicitInstantiations
The queue of implicit template instantiations that are required and must be performed within the curr...
bool CheckFunctionConstraints(const FunctionDecl *FD, ConstraintSatisfaction &Satisfaction, SourceLocation UsageLoc=SourceLocation(), bool ForOverloadResolution=false)
Check whether the given function decl's trailing requires clause is satisfied, if any.
ExprResult CheckPlaceholderExpr(Expr *E)
Check for operands with placeholder types and complain if found.
unsigned NonInstantiationEntries
The number of CodeSynthesisContexts that are not template instantiations and, therefore,...
void ActOnFinishCXXInClassMemberInitializer(Decl *VarDecl, SourceLocation EqualLoc, Expr *Init)
This is invoked after parsing an in-class initializer for a non-static C++ class member,...
ExprResult BuildCXXDefaultArgExpr(SourceLocation CallLoc, FunctionDecl *FD, ParmVarDecl *Param, Expr *Init=nullptr)
BuildCXXDefaultArgExpr - Creates a CXXDefaultArgExpr, instantiating the default expr if needed.
bool InstantiateInClassInitializer(SourceLocation PointOfInstantiation, FieldDecl *Instantiation, FieldDecl *Pattern, const MultiLevelTemplateArgumentList &TemplateArgs)
Instantiate the definition of a field from the given pattern.
bool InstantiateClass(SourceLocation PointOfInstantiation, CXXRecordDecl *Instantiation, CXXRecordDecl *Pattern, const MultiLevelTemplateArgumentList &TemplateArgs, TemplateSpecializationKind TSK, bool Complain=true)
Instantiate the definition of a class from a given pattern.
bool CheckLoopHintExpr(Expr *E, SourceLocation Loc)
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.
bool SubstDefaultArgument(SourceLocation Loc, ParmVarDecl *Param, const MultiLevelTemplateArgumentList &TemplateArgs, bool ForCallExpr=false)
Substitute the given template arguments into the default argument.
ExprResult SubstConstraintExpr(Expr *E, const MultiLevelTemplateArgumentList &TemplateArgs)
bool hasUncompilableErrorOccurred() const
Whether uncompilable error has occurred.
@ ConstantEvaluated
The current context is "potentially evaluated" in C++11 terms, but the expression is evaluated at com...
@ PotentiallyEvaluated
The current expression is potentially evaluated at run time, which means that code may be generated t...
unsigned LastEmittedCodeSynthesisContextDepth
The depth of the context stack at the point when the most recent error or warning was produced.
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.
NestedNameSpecifierLoc SubstNestedNameSpecifierLoc(NestedNameSpecifierLoc NNS, const MultiLevelTemplateArgumentList &TemplateArgs)
void ActOnFields(Scope *S, SourceLocation RecLoc, Decl *TagDecl, ArrayRef< Decl * > Fields, SourceLocation LBrac, SourceLocation RBrac, const ParsedAttributesView &AttrList)
void CheckCompletedCXXClass(Scope *S, CXXRecordDecl *Record)
Perform semantic checks on a class definition that has been completing, introducing implicitly-declar...
SmallVector< ExpressionEvaluationContextRecord, 8 > ExprEvalContexts
A stack of expression evaluation contexts.
DiagnosticsEngine & Diags
bool AttachBaseSpecifiers(CXXRecordDecl *Class, MutableArrayRef< CXXBaseSpecifier * > Bases)
Performs the actual work of attaching the given base class specifiers to a C++ class.
ExprResult ConvertParamDefaultArgument(ParmVarDecl *Param, Expr *DefaultArg, SourceLocation EqualLoc)
SmallVector< Module *, 16 > CodeSynthesisContextLookupModules
Extra modules inspected when performing a lookup during a template instantiation.
void runWithSufficientStackSpace(SourceLocation Loc, llvm::function_ref< void()> Fn)
Run some code with "sufficient" stack space.
ExprResult CreateRecoveryExpr(SourceLocation Begin, SourceLocation End, ArrayRef< Expr * > SubExprs, QualType T=QualType())
Attempts to produce a RecoveryExpr after some AST node cannot be created.
bool InstantiateEnum(SourceLocation PointOfInstantiation, EnumDecl *Instantiation, EnumDecl *Pattern, const MultiLevelTemplateArgumentList &TemplateArgs, TemplateSpecializationKind TSK)
Instantiate the definition of an enum from a given pattern.
void UpdateExceptionSpec(FunctionDecl *FD, const FunctionProtoType::ExceptionSpecInfo &ESI)
std::string getTemplateArgumentBindingsText(const TemplateParameterList *Params, const TemplateArgumentList &Args)
Produces a formatted string that describes the binding of template parameters to template arguments.
ExprResult BuildExpressionFromDeclTemplateArgument(const TemplateArgument &Arg, QualType ParamType, SourceLocation Loc)
Given a non-type template argument that refers to a declaration and the type of its corresponding non...
void warnStackExhausted(SourceLocation Loc)
Warn that the stack is nearly exhausted.
bool SubstBaseSpecifiers(CXXRecordDecl *Instantiation, CXXRecordDecl *Pattern, const MultiLevelTemplateArgumentList &TemplateArgs)
Perform substitution on the base class specifiers of the given class template specialization.
void PerformDependentDiagnostics(const DeclContext *Pattern, const MultiLevelTemplateArgumentList &TemplateArgs)
ASTMutationListener * getASTMutationListener() const
ExprResult ActOnFinishFullExpr(Expr *Expr, bool DiscardedValue)
TypeSourceInfo * SubstFunctionDeclType(TypeSourceInfo *T, const MultiLevelTemplateArgumentList &TemplateArgs, SourceLocation Loc, DeclarationName Entity, CXXRecordDecl *ThisContext, Qualifiers ThisTypeQuals, bool EvaluateConstraints=true)
A form of SubstType intended specifically for instantiating the type of a FunctionDecl.
Encodes a location in the source.
A trivial tuple used to represent a source range.
Represents a C++11 static_assert declaration.
Stmt - This represents one statement.
SourceLocation getEndLoc() const LLVM_READONLY
void printPretty(raw_ostream &OS, PrinterHelper *Helper, const PrintingPolicy &Policy, unsigned Indentation=0, StringRef NewlineSymbol="\n", const ASTContext *Context=nullptr) const
SourceRange getSourceRange() const LLVM_READONLY
SourceLocation tokens are not useful in isolation - they are low level value objects created/interpre...
SourceLocation getBeginLoc() const LLVM_READONLY
Represents a reference to a non-type template parameter that has been substituted with a template arg...
std::optional< unsigned > getPackIndex() const
Decl * getAssociatedDecl() const
A template-like entity which owns the whole pattern being substituted.
QualType getParameterType(const ASTContext &Ctx) const
Determine the substituted type of the template parameter.
NonTypeTemplateParmDecl * getParameter() const
Expr * getReplacement() const
Represents a reference to a non-type template parameter pack that has been substituted with a non-tem...
TemplateArgument getArgumentPack() const
Retrieve the template argument pack containing the substituted template arguments.
SourceLocation getParameterPackLocation() const
Retrieve the location of the parameter pack name.
NonTypeTemplateParmDecl * getParameterPack() const
Retrieve the non-type template parameter pack being substituted.
Decl * getAssociatedDecl() const
A template-like entity which owns the whole pattern being substituted.
A structure for storing an already-substituted template template parameter pack.
Wrapper for substituted template type parameters.
Represents the result of substituting a set of types for a template type parameter pack.
Decl * getAssociatedDecl() const
A template-like entity which owns the whole pattern being substituted.
TemplateArgument getArgumentPack() const
unsigned getIndex() const
Returns the index of the replaced parameter in the associated declaration.
Wrapper for substituted template type parameters.
Represents the declaration of a struct/union/class/enum.
void setTagKind(TagKind TK)