Skip to content

Commit 7462793

Browse files
committed
Move default argument instantiation to SemaTemplateInstantiateDecl.cpp.
No functionality change intended.
1 parent 3847a6a commit 7462793

File tree

3 files changed

+86
-77
lines changed

3 files changed

+86
-77
lines changed

clang/include/clang/Sema/Sema.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9101,6 +9101,8 @@ class Sema final {
91019101
TemplateArgumentListInfo &Result,
91029102
const MultiLevelTemplateArgumentList &TemplateArgs);
91039103

9104+
bool InstantiateDefaultArgument(SourceLocation CallLoc, FunctionDecl *FD,
9105+
ParmVarDecl *Param);
91049106
void InstantiateExceptionSpec(SourceLocation PointOfInstantiation,
91059107
FunctionDecl *Function);
91069108
bool CheckInstantiatedFunctionTemplateConstraints(

clang/lib/Sema/SemaExpr.cpp

Lines changed: 3 additions & 77 deletions
Original file line numberDiff line numberDiff line change
@@ -5575,83 +5575,9 @@ bool Sema::CheckCXXDefaultArgExpr(SourceLocation CallLoc, FunctionDecl *FD,
55755575
return true;
55765576
}
55775577

5578-
if (Param->hasUninstantiatedDefaultArg()) {
5579-
Expr *UninstExpr = Param->getUninstantiatedDefaultArg();
5580-
5581-
EnterExpressionEvaluationContext EvalContext(
5582-
*this, ExpressionEvaluationContext::PotentiallyEvaluated, Param);
5583-
5584-
// Instantiate the expression.
5585-
//
5586-
// FIXME: Pass in a correct Pattern argument, otherwise
5587-
// getTemplateInstantiationArgs uses the lexical context of FD, e.g.
5588-
//
5589-
// template<typename T>
5590-
// struct A {
5591-
// static int FooImpl();
5592-
//
5593-
// template<typename Tp>
5594-
// // bug: default argument A<T>::FooImpl() is evaluated with 2-level
5595-
// // template argument list [[T], [Tp]], should be [[Tp]].
5596-
// friend A<Tp> Foo(int a);
5597-
// };
5598-
//
5599-
// template<typename T>
5600-
// A<T> Foo(int a = A<T>::FooImpl());
5601-
MultiLevelTemplateArgumentList MutiLevelArgList
5602-
= getTemplateInstantiationArgs(FD, nullptr, /*RelativeToPrimary=*/true);
5603-
5604-
InstantiatingTemplate Inst(*this, CallLoc, Param,
5605-
MutiLevelArgList.getInnermost());
5606-
if (Inst.isInvalid())
5607-
return true;
5608-
if (Inst.isAlreadyInstantiating()) {
5609-
Diag(Param->getBeginLoc(), diag::err_recursive_default_argument) << FD;
5610-
Param->setInvalidDecl();
5611-
return true;
5612-
}
5613-
5614-
ExprResult Result;
5615-
{
5616-
// C++ [dcl.fct.default]p5:
5617-
// The names in the [default argument] expression are bound, and
5618-
// the semantic constraints are checked, at the point where the
5619-
// default argument expression appears.
5620-
ContextRAII SavedContext(*this, FD);
5621-
LocalInstantiationScope Local(*this);
5622-
runWithSufficientStackSpace(CallLoc, [&] {
5623-
Result = SubstInitializer(UninstExpr, MutiLevelArgList,
5624-
/*DirectInit*/false);
5625-
});
5626-
}
5627-
if (Result.isInvalid())
5628-
return true;
5629-
5630-
// Check the expression as an initializer for the parameter.
5631-
InitializedEntity Entity
5632-
= InitializedEntity::InitializeParameter(Context, Param);
5633-
InitializationKind Kind = InitializationKind::CreateCopy(
5634-
Param->getLocation(),
5635-
/*FIXME:EqualLoc*/ UninstExpr->getBeginLoc());
5636-
Expr *ResultE = Result.getAs<Expr>();
5637-
5638-
InitializationSequence InitSeq(*this, Entity, Kind, ResultE);
5639-
Result = InitSeq.Perform(*this, Entity, Kind, ResultE);
5640-
if (Result.isInvalid())
5641-
return true;
5642-
5643-
Result =
5644-
ActOnFinishFullExpr(Result.getAs<Expr>(), Param->getOuterLocStart(),
5645-
/*DiscardedValue*/ false);
5646-
if (Result.isInvalid())
5647-
return true;
5648-
5649-
// Remember the instantiated default argument.
5650-
Param->setDefaultArg(Result.getAs<Expr>());
5651-
if (ASTMutationListener *L = getASTMutationListener()) {
5652-
L->DefaultArgumentInstantiated(Param);
5653-
}
5654-
}
5578+
if (Param->hasUninstantiatedDefaultArg() &&
5579+
InstantiateDefaultArgument(CallLoc, FD, Param))
5580+
return true;
56555581

56565582
assert(Param->hasInit() && "default argument but no initializer?");
56575583

clang/lib/Sema/SemaTemplateInstantiateDecl.cpp

Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4227,6 +4227,87 @@ static bool addInstantiatedParametersToScope(Sema &S, FunctionDecl *Function,
42274227
return false;
42284228
}
42294229

4230+
bool Sema::InstantiateDefaultArgument(SourceLocation CallLoc, FunctionDecl *FD,
4231+
ParmVarDecl *Param) {
4232+
assert(Param->hasUninstantiatedDefaultArg());
4233+
Expr *UninstExpr = Param->getUninstantiatedDefaultArg();
4234+
4235+
EnterExpressionEvaluationContext EvalContext(
4236+
*this, ExpressionEvaluationContext::PotentiallyEvaluated, Param);
4237+
4238+
// Instantiate the expression.
4239+
//
4240+
// FIXME: Pass in a correct Pattern argument, otherwise
4241+
// getTemplateInstantiationArgs uses the lexical context of FD, e.g.
4242+
//
4243+
// template<typename T>
4244+
// struct A {
4245+
// static int FooImpl();
4246+
//
4247+
// template<typename Tp>
4248+
// // bug: default argument A<T>::FooImpl() is evaluated with 2-level
4249+
// // template argument list [[T], [Tp]], should be [[Tp]].
4250+
// friend A<Tp> Foo(int a);
4251+
// };
4252+
//
4253+
// template<typename T>
4254+
// A<T> Foo(int a = A<T>::FooImpl());
4255+
MultiLevelTemplateArgumentList TemplateArgs
4256+
= getTemplateInstantiationArgs(FD, nullptr, /*RelativeToPrimary=*/true);
4257+
4258+
InstantiatingTemplate Inst(*this, CallLoc, Param,
4259+
TemplateArgs.getInnermost());
4260+
if (Inst.isInvalid())
4261+
return true;
4262+
if (Inst.isAlreadyInstantiating()) {
4263+
Diag(Param->getBeginLoc(), diag::err_recursive_default_argument) << FD;
4264+
Param->setInvalidDecl();
4265+
return true;
4266+
}
4267+
4268+
ExprResult Result;
4269+
{
4270+
// C++ [dcl.fct.default]p5:
4271+
// The names in the [default argument] expression are bound, and
4272+
// the semantic constraints are checked, at the point where the
4273+
// default argument expression appears.
4274+
ContextRAII SavedContext(*this, FD);
4275+
LocalInstantiationScope Local(*this);
4276+
runWithSufficientStackSpace(CallLoc, [&] {
4277+
Result = SubstInitializer(UninstExpr, TemplateArgs,
4278+
/*DirectInit*/false);
4279+
});
4280+
}
4281+
if (Result.isInvalid())
4282+
return true;
4283+
4284+
// Check the expression as an initializer for the parameter.
4285+
InitializedEntity Entity
4286+
= InitializedEntity::InitializeParameter(Context, Param);
4287+
InitializationKind Kind = InitializationKind::CreateCopy(
4288+
Param->getLocation(),
4289+
/*FIXME:EqualLoc*/ UninstExpr->getBeginLoc());
4290+
Expr *ResultE = Result.getAs<Expr>();
4291+
4292+
InitializationSequence InitSeq(*this, Entity, Kind, ResultE);
4293+
Result = InitSeq.Perform(*this, Entity, Kind, ResultE);
4294+
if (Result.isInvalid())
4295+
return true;
4296+
4297+
Result =
4298+
ActOnFinishFullExpr(Result.getAs<Expr>(), Param->getOuterLocStart(),
4299+
/*DiscardedValue*/ false);
4300+
if (Result.isInvalid())
4301+
return true;
4302+
4303+
// Remember the instantiated default argument.
4304+
Param->setDefaultArg(Result.getAs<Expr>());
4305+
if (ASTMutationListener *L = getASTMutationListener())
4306+
L->DefaultArgumentInstantiated(Param);
4307+
4308+
return false;
4309+
}
4310+
42304311
void Sema::InstantiateExceptionSpec(SourceLocation PointOfInstantiation,
42314312
FunctionDecl *Decl) {
42324313
const FunctionProtoType *Proto = Decl->getType()->castAs<FunctionProtoType>();

0 commit comments

Comments
 (0)