forked from OSchip/llvm-project
If we run into multiple errors within the same template instantiation,
only print the template instantiation backtrace for the first error. Also, if a base class has failed to type-check during instantiation, just drop that base class and continue on to check other base classes. llvm-svn: 66563
This commit is contained in:
parent
79fc0e9250
commit
2a72edd413
|
@ -243,7 +243,10 @@ public:
|
|||
/// The primitive diagnostic helpers.
|
||||
DiagnosticBuilder Diag(SourceLocation Loc, unsigned DiagID) {
|
||||
DiagnosticBuilder DB = Diags.Report(FullSourceLoc(Loc, SourceMgr), DiagID);
|
||||
if (!Diags.isBuiltinNote(DiagID) && !ActiveTemplateInstantiations.empty())
|
||||
if (!Diags.isBuiltinNote(DiagID) &&
|
||||
!ActiveTemplateInstantiations.empty() &&
|
||||
ActiveTemplateInstantiations.back().Entity
|
||||
!= LastTemplateInstantiationErrorContext)
|
||||
DB << PostDiagnosticHook(PrintInstantiationStackHook, this);
|
||||
return DB;
|
||||
}
|
||||
|
@ -1691,6 +1694,15 @@ public:
|
|||
llvm::SmallVector<ActiveTemplateInstantiation, 16>
|
||||
ActiveTemplateInstantiations;
|
||||
|
||||
/// \brief The last template from which a template instantiation
|
||||
/// error or warning was produced.
|
||||
///
|
||||
/// This value is used to suppress printing of redundant template
|
||||
/// instantiation backtraces when there are multiple errors in the
|
||||
/// same instantiation. FIXME: Does this belong in Sema? It's tough
|
||||
/// to implement it anywhere else.
|
||||
ClassTemplateSpecializationDecl *LastTemplateInstantiationErrorContext;
|
||||
|
||||
/// \brief A stack object to be created when performing template
|
||||
/// instantiation.
|
||||
///
|
||||
|
|
|
@ -56,7 +56,10 @@ Sema::InstantiatingTemplate::~InstantiatingTemplate() {
|
|||
|
||||
/// \brief Post-diagnostic hook for printing the instantiation stack.
|
||||
void Sema::PrintInstantiationStackHook(unsigned, void *Cookie) {
|
||||
static_cast<Sema*>(Cookie)->PrintInstantiationStack();
|
||||
Sema &SemaRef = *static_cast<Sema*>(Cookie);
|
||||
SemaRef.PrintInstantiationStack();
|
||||
SemaRef.LastTemplateInstantiationErrorContext
|
||||
= SemaRef.ActiveTemplateInstantiations.back().Entity;
|
||||
}
|
||||
|
||||
/// \brief Prints the current instantiation stack through a series of
|
||||
|
@ -503,7 +506,7 @@ Sema::InstantiateBaseSpecifiers(
|
|||
for (ClassTemplateSpecializationDecl::base_class_iterator
|
||||
Base = ClassTemplate->getTemplatedDecl()->bases_begin(),
|
||||
BaseEnd = ClassTemplate->getTemplatedDecl()->bases_end();
|
||||
Base != BaseEnd && !Invalid; ++Base) {
|
||||
Base != BaseEnd; ++Base) {
|
||||
if (!Base->getType()->isDependentType()) {
|
||||
// FIXME: Allocate via ASTContext
|
||||
InstantiatedBases.push_back(new CXXBaseSpecifier(*Base));
|
||||
|
@ -533,7 +536,8 @@ Sema::InstantiateBaseSpecifiers(
|
|||
Invalid = true;
|
||||
}
|
||||
|
||||
if (AttachBaseSpecifiers(ClassTemplateSpec, &InstantiatedBases[0],
|
||||
if (!Invalid &&
|
||||
AttachBaseSpecifiers(ClassTemplateSpec, &InstantiatedBases[0],
|
||||
InstantiatedBases.size()))
|
||||
Invalid = true;
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
// RUN: clang -fsyntax-only -verify %s
|
||||
template<typename T> struct A; // expected-note 2{{template is declared here}}
|
||||
template<typename T> struct A; // expected-note 4{{template is declared here}}
|
||||
|
||||
template<typename T> struct B : A<T*> { }; // expected-error{{implicit instantiation of undefined template}} \
|
||||
// expected-error{{implicit instantiation of undefined template 'struct A<X *>'}}
|
||||
|
@ -21,3 +21,12 @@ typedef struct { } X;
|
|||
void g() {
|
||||
(void)sizeof(B<X>); // expected-note{{in instantiation of template class 'struct B<X>' requested here}}
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
struct G : A<T>, // expected-error{{implicit instantiation of undefined template 'struct A<int>'}}
|
||||
A<T*> // expected-error{{implicit instantiation of undefined template 'struct A<int *>'}}
|
||||
{ };
|
||||
|
||||
void h() {
|
||||
(void)sizeof(G<int>); // expected-note{{in instantiation of template class 'struct G<int>' requested here}}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue