Use a separate diagnostic for default function argument expressions.

llvm-svn: 81062
This commit is contained in:
Anders Carlsson
2009-09-05 05:14:19 +00:00
parent 88f07cd49c
commit 657bad441e
5 changed files with 67 additions and 11 deletions

View File

@@ -977,6 +977,9 @@ def note_template_static_data_member_def_here : Note<
def note_default_arg_instantiation_here : Note<
"in instantiation of default argument for '%0' required here">;
def note_default_function_arg_instantiation_here : Note<
"in instantiation of default function argument expression "
"for '%0' required here">;
def note_explicit_template_arg_substitution_here : Note<
"while substituting explicitly-specified template arguments into function "
"template %f, here">;

View File

@@ -2730,6 +2730,11 @@ public:
/// FIXME: Use a TemplateArgumentList
DefaultTemplateArgumentInstantiation,
/// We are instantiating a default argument for a function.
/// The Entity is the ParmVarDecl, and TemplateArgs/NumTemplateArgs
/// provides the template arguments as specified.
DefaultFunctionArgumentInstantiation,
/// We are substituting explicit template arguments provided for
/// a function template. The entity is a FunctionTemplateDecl.
ExplicitTemplateArgumentSubstitution,
@@ -2778,7 +2783,9 @@ public:
case DefaultTemplateArgumentInstantiation:
case ExplicitTemplateArgumentSubstitution:
case DeducedTemplateArgumentSubstitution:
case DefaultFunctionArgumentInstantiation:
return X.TemplateArgs == Y.TemplateArgs;
}
return true;
@@ -2852,6 +2859,12 @@ public:
unsigned NumTemplateArgs,
SourceRange InstantiationRange = SourceRange());
InstantiatingTemplate(Sema &SemaRef, SourceLocation PointOfInstantiation,
ParmVarDecl *Param,
const TemplateArgument *TemplateArgs,
unsigned NumTemplateArgs,
SourceRange InstantiationRange = SourceRange());
/// \brief Note that we have finished instantiating this template.
void Clear();

View File

@@ -2573,12 +2573,9 @@ Sema::OwningExprResult Sema::BuildCXXDefaultArgExpr(SourceLocation CallLoc,
// Instantiate the expression.
MultiLevelTemplateArgumentList ArgList = getTemplateInstantiationArgs(FD);
// FIXME: We should really make a new InstantiatingTemplate ctor
// that has a better message - right now we're just piggy-backing
// off the "default template argument" error message.
InstantiatingTemplate Inst(*this, CallLoc, FD->getPrimaryTemplate(),
ArgList.getInnermost().getFlatArgumentList(),
InstantiatingTemplate Inst(*this, CallLoc, Param,
ArgList.getInnermost().getFlatArgumentList(),
ArgList.getInnermost().flat_size());
OwningExprResult Result = SubstExpr(UninstExpr, ArgList);

View File

@@ -164,6 +164,30 @@ Sema::InstantiatingTemplate::InstantiatingTemplate(Sema &SemaRef,
}
}
Sema::InstantiatingTemplate::InstantiatingTemplate(Sema &SemaRef,
SourceLocation PointOfInstantation,
ParmVarDecl *Param,
const TemplateArgument *TemplateArgs,
unsigned NumTemplateArgs,
SourceRange InstantiationRange)
: SemaRef(SemaRef) {
Invalid = CheckInstantiationDepth(PointOfInstantation, InstantiationRange);
if (!Invalid) {
ActiveTemplateInstantiation Inst;
Inst.Kind
= ActiveTemplateInstantiation::DefaultFunctionArgumentInstantiation;
Inst.PointOfInstantiation = PointOfInstantation;
Inst.Entity = reinterpret_cast<uintptr_t>(Param);
Inst.TemplateArgs = TemplateArgs;
Inst.NumTemplateArgs = NumTemplateArgs;
Inst.InstantiationRange = InstantiationRange;
SemaRef.ActiveTemplateInstantiations.push_back(Inst);
Invalid = false;
}
}
void Sema::InstantiatingTemplate::Clear() {
if (!Invalid) {
SemaRef.ActiveTemplateInstantiations.pop_back();
@@ -266,6 +290,23 @@ void Sema::PrintInstantiationStack() {
}
break;
case ActiveTemplateInstantiation::DefaultFunctionArgumentInstantiation: {
ParmVarDecl *Param = cast<ParmVarDecl>((Decl *)Active->Entity);
FunctionDecl *FD = cast<FunctionDecl>(Param->getDeclContext());
TemplateDecl *Template = FD->getPrimaryTemplate();
std::string TemplateArgsStr
= TemplateSpecializationType::PrintTemplateArgumentList(
Active->TemplateArgs,
Active->NumTemplateArgs,
Context.PrintingPolicy);
Diags.Report(FullSourceLoc(Active->PointOfInstantiation, SourceMgr),
diag::note_default_function_arg_instantiation_here)
<< (Template->getNameAsString() + TemplateArgsStr)
<< Active->InstantiationRange;
break;
}
}
}
}
@@ -280,6 +321,8 @@ bool Sema::isSFINAEContext() const {
switch(Active->Kind) {
case ActiveTemplateInstantiation::TemplateInstantiation:
case ActiveTemplateInstantiation::DefaultFunctionArgumentInstantiation:
// This is a template instantiation, so there is no SFINAE.
return false;

View File

@@ -10,28 +10,28 @@ template<typename T> void f3(T a, T b = T() + T()); // expected-error{{invalid o
void g() {
f1(10);
f1(S()); // expected-note{{in instantiation of default argument for 'f1<struct S>' required here}}
f1(S()); // expected-note{{in instantiation of default function argument expression for 'f1<struct S>' required here}}
f2(10);
f2(S());
f3(10);
f3(S()); // expected-note{{in instantiation of default argument for 'f3<struct S>' required here}}
f3(S()); // expected-note{{in instantiation of default function argument expression for 'f3<struct S>' required here}}
}
template<typename T> struct F {
F(T t = 10);
F(T t = 10);
};
struct FD : F<int> { };
void g2() {
F<int> f;
F<int> f;
FD fd;
}
template<typename T> struct G {
G(T) {}
G(T) {}
};
void s(G<int> flags = 10) { }